diff --git a/.editorconfig b/.editorconfig index 6e87a003d..2731d1029 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,12 +1,12 @@ -# Editor configuration, see http://editorconfig.org root = true [*] -charset = utf-8 indent_style = space indent_size = 2 -insert_final_newline = true +end_of_line = lf +charset = utf-8 trim_trailing_whitespace = true +insert_final_newline = true [*.md] max_line_length = off diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000..31033da12 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,9 @@ +**/build/ +**/dist/ +**/coverage/ +**/node_modules/ +jest.config.ts +sponsorkit.config.ts + +# FIXME: Remove +website/ diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 000000000..2ccd45c3d --- /dev/null +++ b/.eslintrc @@ -0,0 +1,117 @@ +{ + "root": true, + "env": { + "node": true + }, + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module", + "project": [ + "./tsconfig.json", + "./benchmarks/tsconfig.json", + "./examples/tsconfig.json", + "./scripts/tsconfig.json", + "./tests/tsconfig.json" + ] + }, + "settings": { + "import/parsers": { + "@typescript-eslint/parser": [".ts"] + }, + "import/resolver": { + "typescript": { + "alwaysTryTypes": true, + "project": [ + "./tsconfig.json", + "./benchmarks/tsconfig.json", + "./examples/tsconfig.json", + "./scripts/tsconfig.json", + "./tests/tsconfig.json" + ] + } + } + }, + "reportUnusedDisableDirectives": true, + "plugins": ["import", "@typescript-eslint", "eslint-plugin-tsdoc", "jest"], + "extends": [ + "airbnb-base", + "airbnb-typescript/base", + "eslint:recommended", + "plugin:@cspell/recommended", + "plugin:@typescript-eslint/recommended", + // "plugin:@typescript-eslint/recommended-type-checked", + "plugin:@typescript-eslint/stylistic", + // "plugin:@typescript-eslint/stylistic-type-checked", + "plugin:import/recommended", + "plugin:import/typescript", + "plugin:jest/recommended", + "prettier" + ], + "rules": { + "tsdoc/syntax": "warn", + "semi": "off", + "@typescript-eslint/semi": "error", + "no-restricted-syntax": "off", + "curly": ["error", "all"], + "nonblock-statement-body-position": ["error", "below"], + "sort-imports": ["error", { "ignoreDeclarationSort": true }], + "import/order": [ + "error", + { + "alphabetize": { + "caseInsensitive": true, + "order": "asc" + }, + "groups": ["builtin", "external", "internal", ["sibling", "parent"], "index", "unknown"], + "newlines-between": "never", + "pathGroups": [ + { "pattern": "@/**", "group": "internal", "position": "before" }, + { "pattern": "type-graphql", "group": "external" } + ], + "pathGroupsExcludedImportTypes": ["builtin"] + } + ], + "import/no-default-export": "error", + "import/prefer-default-export": "off", + "no-unused-vars": "off", + "no-duplicate-imports": "error", + "@typescript-eslint/no-unused-vars": [ + "error", + { + "argsIgnorePattern": "^_", + "varsIgnorePattern": "^_", + "caughtErrorsIgnorePattern": "^_" + } + ], + "@typescript-eslint/array-type": ["error", { "default": "array-simple" }], + "@typescript-eslint/consistent-type-imports": [ + "error", + { + "disallowTypeAnnotations": false, + "fixStyle": "inline-type-imports", + "prefer": "type-imports" + } + ], + "@typescript-eslint/consistent-type-exports": "error", + "@typescript-eslint/consistent-type-definitions": ["error", "interface"], + "@typescript-eslint/no-inferrable-types": [ + "error", + { "ignoreParameters": true, "ignoreProperties": true } + ], + // FIXME: Remove + "@typescript-eslint/ban-types": [ + "error", + { + "types": { + "Function": false, + "Object": false, + "{}": false + }, + "extendDefaults": true + } + ], + // FIXME: Remove + "@typescript-eslint/no-explicit-any": "off" + } +} diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..aecfc23be --- /dev/null +++ b/.gitattributes @@ -0,0 +1,187 @@ +* text=auto eol=lf + +# Source code +*.bash text eol=lf +*.bat text eol=crlf +*.cmd text eol=crlf +*.coffee text +*.css text diff=css +*.htm text diff=html +*.html text diff=html +*.inc text +*.ini text +*.js text +*.json text +*.jsx text +*.less text +*.ls text +*.map text -diff +*.od text +*.onlydata text +*.php text diff=php +*.pl text +*.ps1 text eol=crlf +*.py text diff=python +*.rb text diff=ruby +*.sass text +*.scm text +*.scss text diff=css +*.sh text eol=lf +*.sql text +*.styl text +*.tag text +*.ts text +*.tsx text +*.xml text +*.xhtml text diff=html + +# Docker +Dockerfile text + +# Documentation +*.ipynb text +*.markdown text diff=markdown +*.md text diff=markdown +*.mdwn text diff=markdown +*.mdown text diff=markdown +*.mkd text diff=markdown +*.mkdn text diff=markdown +*.mdtxt text +*.mdtext text +*.txt text +AUTHORS text +CHANGELOG text +CHANGES text +CONTRIBUTING text +COPYING text +copyright text +*COPYRIGHT* text +INSTALL text +license text +LICENSE text +NEWS text +readme text +*README* text +TODO text + +# Templates +*.dot text +*.ejs text +*.erb text +*.haml text +*.handlebars text +*.hbs text +*.hbt text +*.jade text +*.latte text +*.mustache text +*.njk text +*.phtml text +*.svelte text +*.tmpl text +*.tpl text +*.twig text +*.vue text + +# Configs +*.cnf text +*.conf text +*.config text +.editorconfig text +.env text +.gitattributes text +.gitconfig text +.htaccess text +*.lock text -diff +package.json text eol=lf +package-lock.json text -diff +pnpm-lock.yaml text eol=lf -diff +.prettierrc text +yarn.lock text -diff +*.toml text +*.yaml text +*.yml text +browserslist text +Makefile text +makefile text + +# Heroku +Procfile text + +# Graphics +*.ai binary +*.bmp binary +*.eps binary +*.gif binary +*.gifv binary +*.ico binary +*.jng binary +*.jp2 binary +*.jpg binary +*.jpeg binary +*.jpx binary +*.jxr binary +*.pdf binary +*.png binary +*.psb binary +*.psd binary +*.svg text +*.svgz binary +*.tif binary +*.tiff binary +*.wbmp binary +*.webp binary + +# Audio +*.kar binary +*.m4a binary +*.mid binary +*.midi binary +*.mp3 binary +*.ogg binary +*.ra binary + +# Video +*.3gpp binary +*.3gp binary +*.as binary +*.asf binary +*.asx binary +*.avi binary +*.fla binary +*.flv binary +*.m4v binary +*.mng binary +*.mov binary +*.mp4 binary +*.mpeg binary +*.mpg binary +*.ogv binary +*.swc binary +*.swf binary +*.webm binary + +# Archives +*.7z binary +*.gz binary +*.jar binary +*.rar binary +*.tar binary +*.zip binary + +# Fonts +*.ttf binary +*.eot binary +*.otf binary +*.woff binary +*.woff2 binary + +# Executables +*.exe binary +*.pyc binary + +# RC files +*.*rc text + +# Ignore files +*.*ignore text diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..8765d8e17 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @MichalLytek diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index aadb9f7c5..e1fe007f2 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,12 +1,2 @@ -# These are supported funding model platforms - -github: typegraphql # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] -patreon: # Replace with a single Patreon username +github: typegraphql open_collective: typegraphql -ko_fi: # Replace with a single Ko-fi username -tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel -community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry -liberapay: # Replace with a single Liberapay username -issuehunt: # Replace with a single IssueHunt username -otechie: # Replace with a single Otechie username -custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/.github/configs/changelog.json b/.github/configs/changelog.json new file mode 100644 index 000000000..0fbf30d4f --- /dev/null +++ b/.github/configs/changelog.json @@ -0,0 +1,28 @@ +{ + "categories": [ + { + "title": "## πŸš€ Enhancements", + "labels": ["Enhancement πŸ†•"] + }, + { + "title": "## πŸ› Fixes", + "labels": ["Bugfix πŸ› πŸ”¨"] + }, + { + "title": "## πŸ§ͺ Tests", + "labels": ["Test πŸ§ͺ"] + }, + { + "title": "## πŸ“¦ Dependencies", + "labels": ["Dependencies πŸ“¦"] + }, + { + "title": "## πŸ“š Documentation", + "labels": ["Documentation πŸ“–"] + }, + { + "title": "## 🏠 Internal", + "labels": ["Chore πŸ”¨", "Internal 🏠"] + } + ] +} diff --git a/.github/configs/codeql.yml b/.github/configs/codeql.yml new file mode 100644 index 000000000..cc70f26ec --- /dev/null +++ b/.github/configs/codeql.yml @@ -0,0 +1,5 @@ +name: CodeQL Configuration + +paths-ignore: + - "**/node_modules" + - "**/*.test.ts" diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..8f1b38ea3 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,15 @@ +version: 2 +updates: + - package-ecosystem: "npm" + directory: "/" + versioning-strategy: increase + schedule: + interval: "weekly" + ignore: + - dependency-name: "*" + update-types: ["version-update:semver-patch"] + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 000000000..cbf8a594e --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,148 @@ +name: check + +on: + push: + branches: + - master + tags: + - v* + pull_request: + branches: + - master + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + version: + name: Ensure package version match + if: startsWith(github.ref_name, 'v') + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Check Git tag format + env: + TYPE_GRAPHQL_REF_NAME: ${{ github.ref_name }} + run: | + _tag="$TYPE_GRAPHQL_REF_NAME" + if ! printf "%s\n" "$_tag" | grep -q -P '^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-(alpha|beta|rc)\.(0|[1-9][0-9]*))?$'; then + printf '[ERROR]: Git tag (%s) wrong format\n' "$_tag" + exit 1 + fi + + - name: Read package.json version + uses: sergeysova/jq-action@v2 + id: version_package + with: + cmd: jq --raw-output .version package.json + + - name: Read GitHub version + uses: pozetroninc/github-action-get-latest-release@master + id: version_v_github + with: + owner: MichalLytek + repo: type-graphql + excludes: prerelease, draft + + - name: Remove leading v* from GitHub version + id: version_github + env: + TYPE_GRAPHQL_VERSION: ${{ steps.version_v_github.outputs.release }} + run: | + _version="$TYPE_GRAPHQL_VERSION" + printf 'value=%s\n' "${_version#?}" >> "$GITHUB_OUTPUT" + + - name: Read Git tag version + id: version_gittag + env: + TYPE_GRAPHQL_REF_NAME: ${{ github.ref_name }} + run: | + _version="$TYPE_GRAPHQL_REF_NAME" + printf 'value=%s\n' "${_version#?}" >> "$GITHUB_OUTPUT" + + - name: Compare package.json with Git tag + uses: madhead/semver-utils@latest + id: comparison_package_gittag + with: + version: ${{ steps.version_package.outputs.value }} + compare-to: ${{ steps.version_gittag.outputs.value }} + lenient: false + + - name: Compare Git tag with GitHub + uses: madhead/semver-utils@latest + id: comparison_gittag_github + with: + version: ${{ steps.version_gittag.outputs.value }} + compare-to: ${{ steps.version_github.outputs.value }} + lenient: false + + - name: Check package.json == Git tag + env: + TYPE_GRAPHQL_COMPARISON: ${{ steps.comparison_package_gittag.outputs.comparison-result }} + TYPE_GRAPHQL_VERSION_PACKAGE: ${{ steps.version_package.outputs.value }} + TYPE_GRAPHQL_VERSION_TAG: ${{ steps.version_gittag.outputs.value }} + run: | + if [ ! "$TYPE_GRAPHQL_COMPARISON" = "=" ]; then + printf '[ERROR]: package.json (%s) != Git tag (%s)\n' "$TYPE_GRAPHQL_VERSION_PACKAGE" "$TYPE_GRAPHQL_VERSION_TAG" + exit 1 + fi + + - name: Check Git tag > GitHub + env: + TYPE_GRAPHQL_COMPARISON: ${{ steps.comparison_gittag_github.outputs.comparison-result }} + TYPE_GRAPHQL_VERSION_TAG: ${{ steps.version_gittag.outputs.value }} + TYPE_GRAPHQL_VERSION_GITHUB: ${{ steps.version_github.outputs.value }} + run: | + if [ ! "$TYPE_GRAPHQL_COMPARISON" = ">" ]; then + printf '[ERROR]: Git tag (%s) !> GitHub (%s)\n' "$TYPE_GRAPHQL_VERSION_TAG" "$TYPE_GRAPHQL_VERSION_GITHUB" + exit 1 + fi + + check: + name: Build & Lint & Test + needs: version + if: always() && (needs.version.result == 'success' || needs.version.result == 'skipped') + runs-on: ubuntu-latest + strategy: + fail-fast: true + matrix: + node-version: [18.x, 20.x] + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + + - name: Install Dependencies + run: | + npm ci + + - name: Build + run: | + npm run build + npm run build:benchmarks + + - name: Check + run: | + npm run check + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Test + run: npm run test:ci + env: + CI: true + + - name: Upload code coverage + uses: codecov/codecov-action@v4 + if: matrix.node-version == '20.x' diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 000000000..563e38baf --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,43 @@ +name: codeql + +on: + push: + branches: + - master + pull_request: + branches: + - master + schedule: + - cron: "0 0 * * 0" + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + strategy: + fail-fast: false + matrix: + language: + - javascript + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + config-file: ./.github/configs/codeql.yml + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/license.yml b/.github/workflows/license.yml new file mode 100644 index 000000000..ce1531935 --- /dev/null +++ b/.github/workflows/license.yml @@ -0,0 +1,22 @@ +name: license + +on: + schedule: + - cron: "0 0 1 1 *" + +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + +jobs: + license: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: FantasticFiasco/action-update-license-year@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index ed3921b9d..000000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,68 +0,0 @@ -name: TypeGraphQL - -on: - push: - branches: - - master - pull_request: - branches: - - master - -jobs: - check: - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [10.13, 10.x, 11.x, 12.x, 13.x, 14.x, 15.x] - - steps: - - uses: actions/checkout@v1 - - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - - - name: Install deps - run: | - npm ci - - - name: Check codebase - run: | - npm run verify - - - name: Run tests - run: npm run test:ci - env: - CI: true - - - name: Upload code coverage results - uses: codecov/codecov-action@v1 - if: matrix.node-version == '15.x' - - deploy-website: - if: github.ref == 'refs/heads/master' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - uses: actions/setup-node@v2 - with: - node-version: "12" - - - name: Build Docusaurus website - run: | - cd website - npm ci - npm run build - - - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./website/build/type-graphql - user_name: "gh-actions" - user_email: "actions@github.com" - commit_message: | - Deploy website - Deploy website version based on diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..dfa656d46 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,90 @@ +name: release + +on: + workflow_run: + workflows: + - check + types: + - completed + +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + +jobs: + release: + name: Release package on NPM + runs-on: ubuntu-latest + if: github.event.workflow_run.conclusion == 'success' && github.ref_name == 'master' && startsWith(github.event.workflow_run.head_branch, 'v') + permissions: + contents: write + id-token: write + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ github.event.workflow_run.head_branch }} + + - name: Determine if version is prerelease + id: prerelease + env: + TYPE_GRAPHQL_VERSION: ${{ github.event.workflow_run.head_branch }} + run: | + _prerelease= + if printf "%s\n" "$TYPE_GRAPHQL_VERSION" | grep -q -P '^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$'; then + _prerelease=false + else + _prerelease=true + fi + + printf 'value=%s\n' "$_prerelease" >> "$GITHUB_OUTPUT" + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20.x + registry-url: "https://registry.npmjs.org" + + - name: Install latest npm + run: | + npm install -g npm@latest + + - name: Install Dependencies + run: | + npm ci + + - name: Prepare package + run: | + npm run prepublishOnly + env: + TYPE_GRAPHQL_REF: ${{ github.event.workflow_run.head_branch }} + + - name: Build Changelog + id: changelog + uses: mikepenz/release-changelog-builder-action@v4 + with: + configuration: "./.github/configs/changelog.json" + failOnError: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ github.event.workflow_run.head_branch }} + body: ${{ steps.changelog.outputs.changelog }} + prerelease: ${{ steps.prerelease.outputs.value == 'true' }} + + - name: Publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + TYPE_GRAPHQL_PRERELEASE: ${{ steps.prerelease.outputs.value }} + run: | + _tag= + if [ "$TYPE_GRAPHQL_PRERELEASE" = "true" ]; then + _tag="next" + else + _tag="latest" + fi + + npm publish --ignore-scripts --tag "$_tag" diff --git a/.github/workflows/sponsor.yml b/.github/workflows/sponsor.yml new file mode 100644 index 000000000..aef304220 --- /dev/null +++ b/.github/workflows/sponsor.yml @@ -0,0 +1,44 @@ +name: sponsor + +on: + schedule: + - cron: "0 0 * * *" + +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + +jobs: + sponsor: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "18.x" + + - name: Install Dependencies + run: | + npm ci + + - name: Regenerate sponsors images + run: npm run gen:sponsorkit + env: + SPONSORKIT_GITHUB_TOKEN: ${{ secrets.SPONSORKIT_GITHUB_TOKEN }} + # SPONSORKIT_OPENCOLLECTIVE_KEY: ${{ secrets.SPONSORKIT_GITHUB_TOKEN_OPENCOLLECTIVE_TOKEN }} + + - name: Commit updated images + uses: EndBug/add-and-commit@v9 + with: + add: "img/github-sponsors.svg website/static/img/github-sponsors.svg" + message: "chore(sponsors): update sponsors image" + push: true + committer_name: github-actions[bot] + committer_email: github-actions[bot]@users.noreply.github.com + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml new file mode 100644 index 000000000..4fc88a492 --- /dev/null +++ b/.github/workflows/website.yml @@ -0,0 +1,48 @@ +name: website + +on: + workflow_run: + workflows: + - check + types: + - completed + +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + +jobs: + website: + name: Publish website + runs-on: ubuntu-latest + if: github.event.workflow_run.conclusion == 'success' && github.ref_name == 'master' && (github.event.workflow_run.head_branch == 'master' || startsWith(github.event.workflow_run.head_branch, 'v')) + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ github.event.workflow_run.head_branch }} + fetch-depth: 0 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20.x + + - name: Install Dependencies + run: | + npm ci + npm ci --prefix ./website + + - name: Build + run: | + npm run build --prefix ./website + + - name: Publish + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./website/build/type-graphql + user_name: "github-actions[bot]" + user_email: "github-actions[bot]@users.noreply.github.com" + full_commit_message: | + Deploy website based on ${{ github.event.workflow_run.head_sha }} diff --git a/.gitignore b/.gitignore index c2385eead..93127e69b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,26 @@ -# node modules -node_modules +# Node.js modules +**/node_modules/ -# builded sources -build -dist +# Builded sources +**/build/ +**/dist/ -# coverage reports -coverage +# Coverage +**/coverage/ # IntelliJ stuffs .idea/ -# parcel cache +# Parcel cache .cache +.parcel-cache + +# Sponsorkit cache +./images/.cache.json + +# Environments +.env + +# Archives +*.tar.gz +*.tgz diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 000000000..6e3fb3e87 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,6 @@ +#!/usr/bin/env sh + +# shellcheck disable=SC1007 source=SCRIPTDIR/_/husky.sh +. "$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)/_/husky.sh" + +npx --no -- lint-staged diff --git a/.lintstagedrc b/.lintstagedrc new file mode 100644 index 000000000..0969cc0f1 --- /dev/null +++ b/.lintstagedrc @@ -0,0 +1,5 @@ +{ + "**/*.ts": ["eslint --fix", "prettier --write"], + "**/*.md": ["markdownlint --fix", "prettier --write"], + "!**/*.{ts,md}": "prettier --write --ignore-unknown" +} diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 000000000..83f4cbff6 --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,5 @@ +{ + "default": true, + "line-length": false, + "no-blanks-blockquote": false +} diff --git a/.markdownlintignore b/.markdownlintignore new file mode 100644 index 000000000..1d3b5fba4 --- /dev/null +++ b/.markdownlintignore @@ -0,0 +1,20 @@ +**/build/ +**/dist/ +**/coverage/ +**/node_modules/ +website/blog/2018-03-25-medium-article.md +website/blog/2020-08-19-devto-article.md +website/versioned_docs/version-0.16.0/ +website/versioned_docs/version-0.17.0/ +website/versioned_docs/version-0.17.1/ +website/versioned_docs/version-0.17.2/ +website/versioned_docs/version-0.17.4/ +website/versioned_docs/version-0.17.5/ +website/versioned_docs/version-0.17.6/ +website/versioned_docs/version-1.0.0/ +website/versioned_docs/version-1.1.0/ +website/versioned_docs/version-1.1.1/ +website/versioned_docs/version-1.2.0-rc.1/ + +# FIXME: Remove +CHANGELOG.md diff --git a/.npmrc b/.npmrc new file mode 100644 index 000000000..b6f27f135 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +engine-strict=true diff --git a/.prettierignore b/.prettierignore index eb031a538..fafc89c4b 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,18 +1,8 @@ -# node modules -node_modules - -# builded sources -build -dist - -# coverage reports -coverage - -# IntelliJ stuffs -.idea/ - -# parcel cache -.cache - -# changelog -CHANGELOG.md +**/build/ +**/dist/ +**/coverage/ +**/node_modules/ +/.husky/_/ +/.gitattributes +website/versioned_docs +website/versioned_sidebars diff --git a/.prettierrc b/.prettierrc index 3cbe4676f..eeb8f342c 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,4 +1,5 @@ { + "endOfLine": "lf", "trailingComma": "all", "tabWidth": 2, "printWidth": 100, diff --git a/.shellcheckrc b/.shellcheckrc new file mode 100644 index 000000000..8226afb6b --- /dev/null +++ b/.shellcheckrc @@ -0,0 +1 @@ +external-sources=true diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 000000000..bc3954a7d --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,15 @@ +{ + "recommendations": [ + "bierner.comment-tagged-templates", + "DavidAnson.vscode-markdownlint", + "dbaeumer.vscode-eslint", + "EditorConfig.EditorConfig", + "esbenp.prettier-vscode", + "GitHub.vscode-github-actions", + "GraphQL.vscode-graphql", + "streetsidesoftware.code-spell-checker", + "timonwong.shellcheck", + "tlent.jest-snapshot-language-support", + "wayou.vscode-todo-highlight" + ] +} diff --git a/.vscode/launch.json b/.vscode/launch.json index 4c3716b40..61cf16458 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,32 +5,48 @@ "version": "0.2.0", "configurations": [ { + "name": "Run example project", "type": "node", "request": "launch", - "name": "Launch example", - "runtimeArgs": ["-r", "ts-node/register/transpile-only"], - "args": ["${workspaceFolder}/examples/dev.js"], - "env": { "TS_NODE_PROJECT": "${workspaceFolder}/examples/tsconfig.json" }, - "protocol": "inspector", - "sourceMaps": true, - "smartStep": true, - "internalConsoleOptions": "neverOpen", - "console": "integratedTerminal" - }, + "cwd": "${workspaceFolder}/examples/${input:exampleProjectName}", + "args": ["./index.ts"], + "runtimeArgs": ["--nolazy", "-r", "ts-node/register/transpile-only"], + "skipFiles": ["/**"] + } + ], + "inputs": [ { - "type": "node", - "request": "launch", - "name": "Debug current test", - "program": "${workspaceFolder}/node_modules/.bin/jest", - "args": ["--watch", "--runInBand", "${fileBasenameNoExtension}"], - "sourceMaps": true, - "smartStep": true, - "console": "integratedTerminal", - "internalConsoleOptions": "neverOpen", - "disableOptimisticBPs": true, - "windows": { - "program": "${workspaceFolder}/node_modules/jest/bin/jest" - } + "id": "exampleProjectName", + "description": "Choose an example to run", + "type": "pickString", + // TODO: add new examples here + "options": [ + "apollo-cache", + "apollo-federation", + "apollo-federation-2", + "authorization", + "automatic-validation", + "custom-validation", + "enums-and-unions", + "extensions", + "generic-types", + "graphql-scalars", + "interfaces-inheritance", + "middlewares-custom-decorators", + "mikro-orm", + "mixin-classes", + "query-complexity", + "redis-subscriptions", + "resolvers-inheritance", + "simple-subscriptions", + "simple-usage", + "tsyringe", + "typegoose", + "typeorm-basic-usage", + "typeorm-lazy-relations", + "using-container", + "using-scoped-container" + ] } ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 97bef4c57..9ec04569e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,11 @@ { - "typescript.tsdk": "./node_modules/typescript/lib" + "typescript.tsdk": "${workspaceFolder}/node_modules/typescript/lib", + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "[jsonc]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" + } } diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index c6d43a1ff..000000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "label": "Jest watch", - "type": "shell", - "command": "npx", - "problemMatcher": [], - "args": ["jest", "--watch", "${input:filePattern}"] - } - ], - "inputs": [ - { - "type": "promptString", - "id": "filePattern", - "description": "Jest test file name pattern" - } - ] -} diff --git a/CHANGELOG.md b/CHANGELOG.md index 288e05694..70f66e9d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,45 +1,128 @@ # Changelog and release notes - -## v1.2.0-rc.1 + + +## v2.0.0-rc.1 + +## Features + +- support other `Reflect` polyfills than `reflect-metadata` by checking only used `Reflect` API (#1102) + +## Fixes + +- properly override fields of `@ArgsType` classes in deeply nested inheritance chain (#1644) +- allow for leading spaces and multiline directives definitions in `@Directive` decorator (#1423) + +## v2.0.0-beta.6 + +### Fixes + +- allow overriding field resolver method with different `name` arguments (#1284) +- allow object type's `name` argument string contain a double underscore (`__`) when using `buildTypeDefsAndResolvers()` (#1309) + +### Others + +- **Breaking Change**: update `graphql-scalars` peer dependency to `^1.22.4` +- properly configure esm build pipeline to publish working esm version of the package + +## v2.0.0-beta.4 + +### Features + +- **Breaking Change**: expose shim as a package entry point `type-graphql/shim` (and `/node_modules/type-graphql/build/typings/shim.ts`) +- **Breaking Change**: update `graphql-js` peer dependency to `^16.8.1` +- **Breaking Change**: use `@graphql-yoga` instead of `graphql-subscriptions` as the subscriptions engine +- **Breaking Change**: require providing `PubSub` implementation into `buildSchema` option when using `@Subscription` +- **Breaking Change**: remove `@PubSub` in favor of directly importing created `PubSub` implementation +- **Breaking Change**: remove `Publisher` and `PubSubEngine` types +- **Breaking Change**: rename interface `ResolverFilterData` into `SubscriptionHandlerData` and `ResolverTopicData` into `SubscribeResolverData` +- support defining directives on `@Field` of `@Args` +- support defining directives on inline `@Arg` +- allow passing custom validation function as `validateFn` option of `@Arg` and `@Args` decorators +- add support for dynamic topic id function in `@Subscription` decorator option + +## v2.0.0-beta.3 + ### Features + +- **Breaking Change**: update `graphql-js` peer dependency to `^16.7.1` +- **Breaking Change**: upgrade `ArgumentValidationError` and replace `UnauthorizedError` and `ForbiddenError` with `AuthenticationError`, `AuthorizationError` that are extending `GraphQLError` to let the error details be accessible in the `extensions` property +- **Breaking Change**: change `ClassType` constraint from `ClassType` to `ClassType` in order to make it work properly with new TS features +- **Breaking Change**: remove `dateScalarMode` option from `buildSchema` +- **Breaking Change**: make `graphql-scalars` package a peer dependency and use date scalars from it instead of custom ones +- **Breaking Change**: exported `GraphQLISODateTime` scalar has now a name `DateTimeISO` +- **Breaking Change**: change `ValidatorFn` signature from `ValidatorFn` to `ValidatorFn` +- support custom validation function getting resolver data on validate +- bring compatibility with the ESM ecosystem by exposing the double bundle of the `type-graphql` package (CJS and ESM versions) + +### Fixes + +- allow `ValidatorFn` to accept array of values (instead of only `object | undefined`) + +## v2.0.0-beta.2 + +### Features + - **Breaking Change**: `AuthChecker` type is now "function or class" - update to `AuthCheckerFn` if the function form is needed in the code +- **Breaking Change**: update `graphql-js` peer dependency to `^16.6.0` +- **Breaking Change**: `buildSchemaSync` is now also checking the generated schema for errors +- **Breaking Change**: `validate` option of `buildSchema` is set to `false` by default - integration with `class-validator` has to be turned on explicitly +- **Breaking Change**: `validate` option of `buildSchema` doesn't accept anymore a custom validation function - use `validateFn` option instead - support class-based auth checker, which allows for dependency injection - allow defining directives for interface types and theirs fields, with inheritance for object types fields (#744) - allow deprecating input fields and args (#794) - support disabling inferring default values (#793) - support readonly arrays for roles of `@Authorized` decorator (#935) - add sync version of `buildTypeDefsAndResolvers` function (#803) +- lift restriction of listing all interfaces from inheritance chain in `implements` option of `@ObjectType` decorator (#1425) + ### Fixes + - **Breaking Change**: properly emit types nullability when `defaultValue` is provided and remove `ConflictingDefaultWithNullableError` error (#751) - allow defining extension on field resolver level for fields also defined as a property of the class (#776) - fix throwing error when schema with dynamic default value was built again (#787) - fix converting inputs with fields of nested array type (#801) - disable broken exposing input types fields under a changed name via `@Field({ name: "..." })` +- support overwriting fields of extended types (#1109) +- properly execute args validation for nullable items array (#1328) + ### Others -- **Breaking Change**: update `graphql-js` peer dependency to `^15.5.0` + +- **Breaking Change**: update `class-validator` peer dependency to `>=0.14.0` +- **Breaking Change**: change build config to ES2021 - drop support for Node.js < 16.16.0 +- **Breaking Change**: remove support for loading resolvers by glob paths (`resolvers: string[]` build schema option) +- **Breaking Change**: remove `isAbstract` legacy decorator option +- **Breaking Change**: remove the `commentDescriptions` option from `PrintSchemaOptions` (no more support for `#` comments in SDL by GraphQL v16) ## v1.1.1 + ### Fixes + - fix crashing when of union's or interface type's `resolveType` function returns `undefined` or `null` (#731) - fix crashing when no reflected type available for fields with params decorators (#724) - fix not registering object types implementing interface type when interface type is used as object type field type (#736) - properly transform nested array of input type classes (#737) ## v1.1.0 + ### Features + - allow passing custom validation function as `validate` option to `buildSchema` - support defining deprecation reason and description of enum members (#714) + ### Fixes + - **Breaking Change**: throw error when wrong type of value provided as arg or input for `GraphQLISODateTime` and `GraphQLTimestamp` scalars - don't include in schema the fields declared as `@FieldResolver` when that resolvers classes aren't provided in `resolvers` array - fix grammar in `CannotDetermineGraphQLTypeError` error message - properly inherit extensions from parent class and its fields ## v1.0.0 + ### Features + - **Breaking Change**: emit in schema only types actually used by provided resolvers classes (#415) - **Breaking Change**: update `graphql-js` peer dependency to `^15.3.0` - **Breaking Change**: update `graphql-query-complexity` dependency to `^0.7.0` and drop support for `fieldConfigEstimator` (use `fieldExtensionsEstimator` instead) @@ -58,7 +141,9 @@ - expose `createResolversMap` utility that generates apollo-like resolvers object - support IoC containers which `.get()` method returns a `Promise` of resolver instance - update deps to newest major versions (`tslib`, `graphql-query-complexity`) + ### Fixes + - **Breaking Change**: stop returning null for `GraphQLTimestamp` and `GraphQLISODateTime` scalars when returned value is not a `Date` instance - now it throws explicit error instead - **Breaking Change**: fix transforming and validating nested inputs and arrays (#462) - refactor union types function syntax handling to prevent possible errors with circular refs @@ -72,61 +157,87 @@ - fix using shared union and interface types in multiple schemas when `resolveType` is used - properly inherit directives while extending `@InputType` or `@ObjectType` classes (#626) - skip transforming empty array items into input classes + ### Others + - **Breaking Change**: change build config to ES2018 - drop support for Node.js < 10.3 - **Breaking Change**: remove deprecated `DepreciationOptions` interface - **Breaking Change**: remove deprecated direct array syntax for declaring union types ## v0.17.6 + ### Fixes + - fix leaking resolver source code in `MissingSubscriptionTopicsError` error message (#489) ## v0.17.5 + ### Features + - rename `DepreciationOptions` interface to `DeprecationOptions` and deprecate the old one - update deps to newest minor versions (`tslib`, `semver`, `graphql-query-complexity` and `glob`) - support nested array types (`@Field(type => [[Int]])`) (#393) - deprecate the direct array syntax for union types + ### Fixes + - fix errors on circular refs in union types (#364) by adding the function syntax (`() => TClassTypes`) ## v0.17.4 + ### Features + - add support for creating custom parameter decorators (#329) - allow to provide custom `subscribe` function in `@Subscription` decorator (#328) ## v0.17.3 + ### Features -- update packages `semver` to `^6.0.0` and `graphql-subscriptions` to `^1.1.0` + +- update packages `semver` to `^6.0.0` and `graphql-subscriptions` to `^1.1.0` + ### Fixes + - fix broken compatibility with newer `@types/graphql` due to using removed private types (e.g. `MaybePromise`) (#320) ## v0.17.2 + ### Features + - add support for defining `resolveType` function for interfaces and unions (#319) - add support for setting default nullability for fields and return types (#297) - add `skipCheck` option in `buildSchema` to disable checking the correctness of a schema - add postinstall script for printing info on console about supporting the project + ### Fixes + - fix generating plain resolvers for queries and mutations (compatibility with Apollo client state) ## v0.17.1 + ### Features + - add support for emitting schema file in not existing directory (#269) - drop support for Node.js v6 (end of LTS in April 2019) + ### Fixes + - fix typings discovery support for WebStorm (#276) - allow for returning plain objects when using `ObjectType`s that implements `InterfaceType`s or extends other classes (#160) ## v0.17.0 + ### Features + - **Breaking Change**: make `graphql-js` packages a peer dependencies, bump `graphql` to `^14.1.1` and `@types/graphql` to `^14.0.7` (#239) - **Breaking Change**: remove `useContainer` function and allow to register container by `buildSchema` options (#241) - **Breaking Change**: change the default `PrintSchemaOptions` option `commentDescriptions` to false (no more `#` comments in SDL) - add support for passing `PrintSchemaOptions` in `buildSchema.emitSchemaFile` (e.g. `commentDescriptions: true` to restore previous behavior) - add `buildTypeDefsAndResolvers` utils function for generating apollo-like `typeDefs` and `resolvers` pair (#233) - add support for generic types (#255) + ### Fixes + - **Breaking Change**: remove the `formatArgumentValidationError` helper as it's not compatible and not needed in new Apollo Server (#258) - fix calling return type getter function `@Field(type => Foo)` before finishing module evaluation (allow for extending circular classes using `require`) - fix nullifying other custom method decorators - call the method on target instance, not the stored reference to original function (#247) @@ -134,175 +245,250 @@ - prevent unnecessary conversion of an object that is already an instance of the requested type (avoid constructor side-effects) ## v0.16.0 + ### Features + - add support for default values in schema (#203) - add support for lists with nullable items (#211) + ### Fixes + - fix browser shim (compatibility with polyfills for decorator support) ## v0.15.0 + ### Features + - **Breaking Change**: upgrade `graphql` to `^14.0.2`, `graphql-subscriptions` to `^1.0.0` and `@types/graphql` to `^14.0.2` - update all other dependencies - drop support for Node.js v9 -- add capability to emit the schema definition file (*.gql) as a `buildSchema` option +- add capability to emit the schema definition file (\*.gql) as a `buildSchema` option - add `emitSchemaDefinitionFile` helper function for emitting the schema SDL ## v0.14.0 + ### Features + - **Breaking Change**: change `ClassType` type and export it in package index - **Breaking Change**: refactor generic `createUnionType` to remove the 10 types limit (note: requires TypeScript >=3.0.1) - add support for subscribing to dynamic topics - based on args/ctx/root (#137) - add support for query complexity analysis - integration with `graphql-query-complexity` (#139) ## v0.13.1 + ### Fixes + - fix missing loosely typed overload signature for `createUnionType` (remove the 10 types limit) ## v0.13.0 + ### Features + - make `class-validator` a virtual peer dependency and update it to newest `0.9.1` version - add support for creating scoped containers (#113) ## v0.12.3 + ### Features + - add reflect-metadata checks and informative error if no polyfill provided - update `@types/graphql` to latest version (`^0.13.3`) + ### Fixes + - fix throwing error when `of => objectType` wasn't provided in abstract resolver class - fix calling `Object.assign` with boolean arguments (#111) ## v0.12.2 + ### Features + - add support for using type classes in browser (configure webpack to use decorators shim) + ### Fixes + - fix swallowing false argument value (#101) ## v0.12.1 + ### Fixes + - fix bug with overriding methods from parent resolver class (#95) ## v0.12.0 + ### Features + - **Breaking Change**: remove deprecated `ActionData` and `FilterActionData` interfaces - add support for resolver classes inheritance - add `name` decorator option for `@Field` and `@FieldResolver` decorators that allows to set the schema name different than the property name ## v0.11.3 + ### Features + - make auth checker feature generic typed (default `string` for backward compatibility) ## v0.11.2 + ### Features + - attach `MetadataStorage` to global scope (support multiple packages/modules) - rename and deprecate `ActionData` and `FilterActionData` interfaces to `ResolverData` and `ResolverFilterData` ## v0.11.1 + ### Features + - add support for returning null instead of throwing authorization error (`authMode` property of `buildSchema` config) - add support for generating object type field in schema from method with `@FieldResolver` + ### Fixes + - fix bug when converting object scalars to target class instance (#65) ## v0.11.0 + ### Features + - add support for creating and attaching middlewares, guards and interceptors to fields and resolvers - **Breaking Change**: remove deprecated decorators with `GraphQL` prefix and `{ array: true }` type option ## v0.10.0 + ### Features + - add `buildSchemaSync` function to build the schema synchronously (unsafe! without additional errors checks) - update package dependencies - **Breaking Change**: update `@types/graphql` to `0.13.0` + ### Fixes + - decorator option `validate` is now merged with `buildSchema`'s `validate` config instead of overwriting it ## v0.9.1 + ### Fixes + - fix bug with extending non-TypeGraphQL classes ## v0.9.0 + ### Features + - add support for GraphQL subscriptions using `graphql-subscriptions` - update package dependencies - deprecate `{ array: true }` type option ## v0.8.1 + ### Features + - add `@Info()` decorator for injecting GraphQL resolve info to resolvers - add support for injecting parts of `root` and `context` objects with `@Root("field")` and `@Ctx("field")` decorators ## v0.8.0 + ### Features + - add base support for GraphQL enums using TypeScript enums - add support for defining GraphQL unions - add support for importing resolvers from file path glob - deprecate decorators with `GraphQL` prefix - use `@ArgsType`, `@InputType`, `@InterfaceType`, `@ObjectType` and `@Resolver` instead + ### Fixes + - fix not working array type notation in circular dependencies (correct thunk generation) ## v0.7.0 + ### Features + - add authorization feature - `@Authorized` decorator and `authChecker` function in schema options ([see docs](https://github.com/MichalLytek/type-graphql/blob/master/docs/authorization.md)) - add support for defining array type using mongoose-like notation `[Type]` - **Breaking Change**: remove deprecated `@GraphQLArgumentType` decorator - use `@GraphQLArgsType` instead ## v0.6.0 + ### Features + - add support for defining GraphQL interfaces and implementing it by object types - add support for extending input, args, object and interface types classes - add support for implementing GraphQL interfaces without decorators duplication - **Breaking Change**: make `buildSchema` async - now it returns a Promise of `GraphQLSchema` - rename and deprecate `@GraphQLArgumentType` decorator - use `@GraphQLArgsType` instead + ### Fixes + - allow for no args in `@GraphQLResolver` decorator to keep consistency with other resolver classes ## v0.5.0 + ### Features + - create instance of root object when it's type provided in resolver - change `Date` scalar names to `GraphQLISODateTime` and `GraphQLTimestamp` - support only `Date` objects (instances) serialization in `GraphQLTimestamp` (and in `GraphQLISODateTime` too) - update package dependencies - add test suite with 92%+ coverage + ### Fixes + - **Breaking change**: switch array `nullable` option behavior from `[Type]!` to `[Type!]` - add more detailed type reflection error message (parameters support) - fix `ResolverInterface` resolver function type (allow additional parameters) - add support for named param in `@GraphQLResolver` lambda and for object class as param ## v0.4.0 + ### Features + - add basic support for automatic arguments and inputs validation using `class-validator` - add interface `ResolverInterface` for type checking of resolver class methods (field resolvers) - update `graphql` dependency from `^0.12.3` to `^0.13.0` + ### Fixes + - fix default values for arg/input fields (class property initializers) - use `new` instead of `Object.create` ## v0.3.0 + ### Features + - add support for descriptions in schema (types, args, queries, etc.) - add support for declaring deprecation reason on object fields and queries/mutations + ### Fixes + - fix scalars ID alias (GraphQLID not GraphQLString) ## v0.2.0 + ### Features + - add support for Date type (built-in scalar) - add support for custom scalars (and mapping it to TS types) - change `@Context` decorator name to `@Ctx` ## v0.1.2 + ### Fixes + - fix missing type args in schema when declared in field resolver - fix missing resolver function when defined as type field method - fix creating instances of root object when internal fields are Promises (switch from `plainToClass` to vanilla JS) - fix converting field and resolvers args errors while converting gql objects (weird `prototype` stuffs) ## v0.1.1 + ### Features + - add support for omitting return type when use type options, in selected decorators (`@Field`, `@Arg`) + ### Fixes + - fix class getter resolvers bug - missing fields from prototype (`plainToClass` bug) ## v0.1.0 + ### Initial release diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 83a929231..91a628f93 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,5 @@ + + # Contributing to TypeGraphQL We would love for you to contribute to TypeGraphQL and help make it even better than it is today! @@ -10,7 +12,7 @@ As a contributor, here are the guidelines we would like you to follow: - [Coding Rules](#rules) - [Commit Message Guidelines](#commit) -## Got a Question or Problem? +

Got a Question or Problem?

Do not open issues for general support questions as we want to keep GitHub issues for bug reports and feature requests. @@ -18,12 +20,12 @@ Instead, consider using [Stack Overflow](https://stackoverflow.com/questions/tag You can also ask community for help using the [Github Discussion platform][discussions]. -## Found a Bug? +

Found a Bug?

If you find a bug in the source code, you can help us by [submitting an issue](#submit-issue) to our [GitHub Repository][github]. Even better, you can [submit a Pull Request](#submit-pr) with a failing test case that reproduces the issue. -## Missing a Feature? +

Missing a Feature?

You can _request_ a new feature by [submitting an issue](#submit-issue) to our GitHub Repository. @@ -34,15 +36,15 @@ If you would like to _implement_ a new feature, please consider the size of the - **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr). -## Submission Guidelines +

Submission Guidelines

-### Submitting an Issue +

Submitting an Issue

Before you submit an issue, please search the issue tracker. An issue for your problem may already exist and the discussion might inform you of workarounds readily available. You can file new issues by selecting from our [new issue templates](https://github.com/MichalLytek/type-graphql/issues/new/choose) and filling out the issue template. -### Submitting a Pull Request (PR) +

Submitting a Pull Request (PR)

Before you submit your Pull Request (PR) consider the following guidelines: @@ -97,7 +99,10 @@ If we ask for changes via code reviews then: That's it! Thank you for your contribution! -#### After your pull request is merged + + +### After your pull request is merged + After your pull request is merged, you can safely delete your branch and pull the changes from the main (upstream) repository: @@ -125,19 +130,18 @@ After your pull request is merged, you can safely delete your branch and pull th git pull --ff upstream master ``` -## Coding Rules +

Coding Rules

To ensure consistency throughout the source code, keep these rules in mind as you are working: - All features or bug fixes **must be covered by tests**. -- The code must pass type checking and fullfil all the TSLint rules. +- The code must pass type checking and fullfil all the ESLint rules. -## Commit Message Guidelines +

Commit Message Guidelines

-For more information checkout this [commit rules guide](https://www.conventionalcommits.org/en/v1.0.0/). +For more information checkout this [commit rules guide](https://www.conventionalcommits.org/en/v1.0.0). [github]: https://github.com/MichalLytek/type-graphql [discussions]: https://github.com/MichalLytek/type-graphql/discussions -[stackoverflow]: https://stackoverflow.com/questions/tagged/typegraphql [allow-maintainer-edits]: https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/allowing-changes-to-a-pull-request-branch-created-from-a-fork#enabling-repository-maintainer-permissions-on-existing-pull-requests diff --git a/LICENSE b/LICENSE index a162db387..ec84e4a56 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2018-2021 MichaΕ‚ Lytek +Copyright (c) 2018-2024 MichaΕ‚ Lytek Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 8e6d3c02f..4f1b2cc23 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,29 @@ -![logo](https://raw.githubusercontent.com/MichalLytek/type-graphql/master/img/logo.png) + + +![logo](./images/logo.png) + # TypeGraphQL -[![npm version](https://badge.fury.io/js/type-graphql.svg)](https://badge.fury.io/js/type-graphql) -[![Build Status](https://img.shields.io/github/checks-status/MichalLytek/type-graphql/master)](https://github.com/MichalLytek/type-graphql/actions/workflows/main.yml?query=branch%3Amaster) +[![release](https://github.com/MichalLytek/type-graphql/actions/workflows/release.yml/badge.svg)](https://github.com/MichalLytek/type-graphql/actions/workflows/release.yml) +[![website](https://github.com/MichalLytek/type-graphql/actions/workflows/website.yml/badge.svg)](https://github.com/MichalLytek/type-graphql/actions/workflows/website.yml) +[![codeql](https://github.com/MichalLytek/type-graphql/actions/workflows/codeql.yml/badge.svg)](https://github.com/MichalLytek/type-graphql/actions/workflows/codeql.yml) +[![discord](https://img.shields.io/discord/1195751245386875040?logo=discord&color=%237289da)](https://discord.gg/cWnBAQcbg2) [![codecov](https://codecov.io/gh/MichalLytek/type-graphql/branch/master/graph/badge.svg)](https://codecov.io/gh/MichalLytek/type-graphql) -![dependencies](https://img.shields.io/david/MichalLytek/type-graphql) -[![open collective](https://opencollective.com/typegraphql/tiers/badge.svg)](<(https://opencollective.com/typegraphql)>) -[![install size](https://packagephobia.now.sh/badge?p=type-graphql)](https://packagephobia.now.sh/result?p=type-graphql) +[![npm](https://img.shields.io/npm/v/type-graphql?logo=npm&color=%23CC3534)](https://www.npmjs.com/package/type-graphql) +[![open collective](https://opencollective.com/typegraphql/tiers/badge.svg)](https://opencollective.com/typegraphql) -Create GraphQL schema and resolvers with TypeScript, using classes and decorators! +Create [GraphQL](https://graphql.org) schema and resolvers with [TypeScript](https://www.typescriptlang.org), using classes and decorators! -[**https://typegraphql.com/**](https://typegraphql.com/) -
-
-[![](https://opencollective.com/typegraphql/donate/button.png?color=white)](https://opencollective.com/typegraphql) +**** + +[![donate](https://opencollective.com/typegraphql/donate/button.png?color=black)](https://opencollective.com/typegraphql) ## Introduction **TypeGraphQL** makes developing GraphQL APIs an enjoyable process, i.e. by defining the schema using only classes and a bit of decorator magic. -So, to create types like object type or input type, we use a kind of DTO classes. +So, to create types like object type or input type, we use a kind of DTO class. For example, to declare `Recipe` type we simply create a class and annotate it with decorators: ```ts @@ -51,7 +54,7 @@ type Recipe { } ``` -Then we can create queries, mutations and field resolvers. For this purpose we use controller-like classes that are called "resolvers" by convention. We can also use awesome features like dependency injection and auth guards: +Then we can create queries, mutations and field resolvers. For this purpose, we use controller-like classes that are called "resolvers" by convention. We can also use awesome features like dependency injection and auth guards: ```ts @Resolver(Recipe) @@ -77,7 +80,7 @@ class RecipeResolver { } ``` -And in this simple way we get this part of the schema in SDL: +And in this simple way, we get this part of the schema in SDL: ```graphql type Query { @@ -91,11 +94,11 @@ type Mutation { ## Motivation -We all know that GraphQL is great and solves many problems we have with REST APIs, like overfetching and underfetching. But developing a GraphQL API in Node.js with TypeScript is sometimes a bit of a pain. Why? Let's take a look at the steps we usually have to take. +We all know that GraphQL is great and solves many problems we have with REST APIs, like Over-Fetching and Under-Fetching. But developing a GraphQL API in Node.js with TypeScript is sometimes a bit of a pain. Why? Let's take a look at the steps we usually have to take. -First, we create all the GraphQL types in `schema.gql` using SDL. Then we create our data models using [ORM classes](https://github.com/typeorm/typeorm), which represent our db entities. Then we start to write resolvers for our queries, mutations and fields, but this forces us to first create TS interfaces for all arguments, inputs, and even object types. +First, we create all the GraphQL types in `schema.graphql` using SDL. Then we create our data models using [ORM classes](https://github.com/typeorm/typeorm), which represent our DB entities. Then we start to write resolvers for our queries, mutations and fields, but this forces us to first create TS interfaces for all arguments, inputs, and even object types. -Only then can we actually implement the resolvers using weird generic signatures and manually performing common tasks, like validation, authorization and loading dependencies: +Only then can we implement the resolvers using weird generic signatures and manually performing common tasks, like validation, authorization and loading dependencies: ```ts export const getRecipesResolver: GraphQLFieldResolver = async ( @@ -116,15 +119,15 @@ export const getRecipesResolver: GraphQLFieldResolver models redundancy and developer experience (F2 rename won't work, you have to remember about the codegen watch task in background, etc.), as well as common tasks like validation, authorization, etc. +Tools like [GraphQL Code Generator](https://github.com/dotansimha/graphql-code-generator) or [graphqlgen](https://github.com/prisma/graphqlgen) only solve the first part - they generate the corresponding interfaces (and resolvers skeletons) for our GraphQL schema but they don't fix the schema <--> models redundancy and developer experience (F2 rename won't work, you have to remember about the codegen watch task in the background, etc.), as well as common tasks like validation, authorization, etc. **TypeGraphQL** comes to address these issues, based on experience from a few years of developing GraphQL APIs in TypeScript. The main idea is to have only one source of truth by defining the schema using classes and some help from decorators. Additional features like dependency injection, validation and auth guards help with common tasks that normally we would have to handle ourselves. ## Documentation -The documentation, installation guide, detailed description of the API and all of its features is [available on the website](https://typegraphql.com/). +The documentation, installation guide, and detailed description of the API and all of its features are [available on the website](https://typegraphql.com). ### Getting started @@ -136,59 +139,70 @@ If you prefer video tutorials, you can watch [Ben Awad](https://github.com/benaw ### Examples -You can also check the [examples folder](https://github.com/MichalLytek/type-graphql/tree/master/examples) in this repository for more examples of usage: simple fields resolvers, DI Container support, TypeORM integration, automatic validation, etc. +You can also check the [examples folder](./examples) in this repository for more examples of usage: simple fields resolvers, DI Container support, TypeORM integration, automatic validation, etc. + +The [Tests folder](./tests) might also give you some tips on how to get various things done. + +## Security contact information -The [Tests folder](https://github.com/MichalLytek/type-graphql/tree/master/tests) might also give you some tips how to get various things done. +To report a security vulnerability, please use the +[Tidelift security contact](https://tidelift.com/security). +Tidelift will coordinate the fix and disclosure. ## The future -The currently released version is a stable 1.0.0 release. It is well tested (95% coverage, 428 test cases) and has most of the planned features already implemented. Plenty of companies and independent developers are using it in production with success. +The currently released version is a stable 1.0.0 release. It is well-tested (97% coverage, ~500 test cases) and has most of the planned features already implemented. Plenty of companies and independent developers are using it in production with success. -However, there are also plans for a lot more features like better TypeORM, Prisma and dataloader integration, custom decorators and metadata annotations support - [the full list of ideas](https://github.com/MichalLytek/type-graphql/issues?q=is%3Aissue+is%3Aopen+label%3A"Enhancement+%3Anew%3A") is available on the GitHub repo. You can also keep track of [development's progress on project board](https://github.com/MichalLytek/type-graphql/projects/1). +However, there are also plans for a lot more features like better TypeORM, Prisma and DataLoader integration, custom decorators and metadata annotations support - [the full list of ideas](https://github.com/MichalLytek/type-graphql/issues?q=is%3Aissue+is%3Aopen+label%3A"Enhancement+%3Anew%3A") is available on the GitHub repo. You can also keep track of [development's progress on the project board](https://github.com/MichalLytek/type-graphql/projects/1). If you have any interesting feature requests, feel free to open an issue on GitHub so we can discuss that! ## Support -TypeGraphQL is an MIT-licensed open source project. This framework is a result of the tremendous amount of work - sleepless nights, busy evenings and weekends. +**TypeGraphQL** is an MIT-licensed open-source project. This framework is a result of the tremendous amount of work - sleepless nights, busy evenings and weekends. -It doesn't have a large company that sits behind - its ongoing development is possible only thanks to the support by the community. +It doesn't have a large company that sits behind it - its ongoing development is possible only thanks to the support of the community. -[![](https://opencollective.com/typegraphql/donate/button.png?color=blue)](https://opencollective.com/typegraphql) +[![donate](https://opencollective.com/typegraphql/donate/button.png?color=blue)](https://opencollective.com/typegraphql) ### Gold Sponsors πŸ† -| [](http://career.bluereceipt.co/) | [](https://www.ecadlabs.com/) | -| :---------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------: | -| [**BlueReceipt**](http://career.bluereceipt.co/) | [**ECAD Labs**](https://www.ecadlabs.com/) | - > Please ask your company to support this open source project by [becoming a gold sponsor](https://opencollective.com/typegraphql/contribute/gold-sponsors-8340) and getting a premium technical support from our core contributors. ### Silver Sponsors πŸ₯ˆ -| [](https://gorrion.io/) | [](https://www.chums.co/) | -| :------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------: | -| [**Gorrion Software House**](https://gorrion.io/) | [**Chums**](https://www.chums.co/) | +> Please ask your company to support this open source project by [becoming a silver sponsor](https://opencollective.com/typegraphql/contribute/silver-sponsors-14804). ### Bronze Sponsors πŸ₯‰ -| [](https://www.ligrsystems.com/) | [](https://www.joinlifex.com/) | [](https://www.swissmentor.com/) | -| :---------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------: | -| [**Live Graphic Systems**](https://www.ligrsystems.com/) | [**LifeX Aps**](https://www.joinlifex.com/) | [**SwissMentor**](https://www.swissmentor.com/) | + + +| [live graphic systems](https://www.ligrsystems.com) | [lifeX aps](https://www.joinlifex.com) | [instinctools](https://instinctools.com/manufacturing) | [vps server](https://www.vpsserver.com) | +| :------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------: | +| [**Live Graphic Systems**](https://www.ligrsystems.com) | [**LifeX Aps**](https://www.joinlifex.com/) | [**instinctools**](https://instinctools.com/manufacturing) | [**VPS Server**](https://www.vpsserver.com) | -[![Become a Sponsor](https://opencollective.com/static/images/become_sponsor.svg)](https://opencollective.com/typegraphql) +| [NonGamstopBets](https://www.nongamstopbets.com/casinos-not-on-gamstop/) | [CasinoDeps.co.nz](https://casinodeps.co.nz/1-dollar-casinos/) | [Non Stop Casino](https://uk.nonstopcasino.org/non-gamstop-casinos/) | +| :---------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------: | +| [**NonGamstopBets**](https://www.nongamstopbets.com/casinos-not-on-gamstop/) | [**CasinoDeps**](https://casinodeps.co.nz/1-dollar-casinos/) | [**Non Stop Casino**](https://uk.nonstopcasino.org/non-gamstop-casinos/) | + + + +[![become a sponsor](https://opencollective.com/static/images/become_sponsor.svg)](https://opencollective.com/typegraphql) ### Members πŸ’ͺ -[![](https://opencollective.com/typegraphql/tiers/members.svg?avatarHeight=48&width=890&button=false)](https://opencollective.com/typegraphql#contributors) +[![Members](https://opencollective.com/typegraphql/tiers/members.svg?avatarHeight=45&width=320&button=false)](https://opencollective.com/typegraphql#contributors) -### Backers β˜• +### GitHub Sponsors -[![](https://opencollective.com/typegraphql/tiers/backers.svg?avatarHeight=48&width=890&button=false)](https://opencollective.com/typegraphql#contributors) +[![GitHub Sponsors](./images/github-sponsors.svg)](https://github.com/sponsors/TypeGraphQL) -## Want to help? +## Community -Want to file a bug, contribute some code, or improve documentation? Great! Please read our -guidelines for [contributing][contributing] and then check out one of our [help wanted issues](https://github.com/MichalLytek/type-graphql/labels/Help%20Wanted%20%3Asos%3A). +- Visit the [Official Website](https://typegraphql.com) +- Chat on [Discord](https://discord.gg/cWnBAQcbg2) + +## Want to help? -[contributing]: https://github.com/MichalLytek/type-graphql/blob/master/CONTRIBUTING.md +Want to file a bug, contribute some code, or improve the documentation? Great! Please read our +guidelines for [CONTRIBUTING](./CONTRIBUTING.md) and then check out one of our [help-wanted issues](https://github.com/MichalLytek/type-graphql/labels/Help%20Wanted%20%3Asos%3A). diff --git a/benchmarks/.eslintrc b/benchmarks/.eslintrc new file mode 100644 index 000000000..4c1c8af01 --- /dev/null +++ b/benchmarks/.eslintrc @@ -0,0 +1,13 @@ +{ + "rules": { + "no-console": "off", + "max-classes-per-file": "off", + "class-methods-use-this": "off", + "import/no-extraneous-dependencies": [ + "error", + { + "devDependencies": true + } + ] + } +} diff --git a/benchmarks/array/graphql-js/async.ts b/benchmarks/array/graphql-js/async.ts index 1898f6584..359618514 100644 --- a/benchmarks/array/graphql-js/async.ts +++ b/benchmarks/array/graphql-js/async.ts @@ -1,41 +1,32 @@ import { - GraphQLSchema, - GraphQLObjectType, - GraphQLString, - GraphQLNonNull, GraphQLBoolean, GraphQLInt, GraphQLList, + GraphQLNonNull, + GraphQLObjectType, + GraphQLSchema, + GraphQLString, } from "graphql"; - -import { runBenchmark, ARRAY_ITEMS } from "../run"; +import { ARRAY_ITEMS, runBenchmark } from "../run"; const SampleObjectType: GraphQLObjectType = new GraphQLObjectType({ name: "SampleObject", fields: () => ({ stringField: { type: new GraphQLNonNull(GraphQLString), - resolve: async source => { - return source.stringField; - }, + resolve: async source => source.stringField, }, numberField: { type: new GraphQLNonNull(GraphQLInt), - resolve: async source => { - return source.numberField; - }, + resolve: async source => source.numberField, }, booleanField: { type: new GraphQLNonNull(GraphQLBoolean), - resolve: async source => { - return source.booleanField; - }, + resolve: async source => source.booleanField, }, nestedField: { type: SampleObjectType, - resolve: async source => { - return source.nestedField; - }, + resolve: async source => source.nestedField, }, }), }); diff --git a/benchmarks/array/graphql-js/standard.ts b/benchmarks/array/graphql-js/standard.ts index c6e2b1259..e05eb11f8 100644 --- a/benchmarks/array/graphql-js/standard.ts +++ b/benchmarks/array/graphql-js/standard.ts @@ -1,14 +1,13 @@ import { - GraphQLSchema, - GraphQLObjectType, - GraphQLString, - GraphQLNonNull, GraphQLBoolean, GraphQLInt, GraphQLList, + GraphQLNonNull, + GraphQLObjectType, + GraphQLSchema, + GraphQLString, } from "graphql"; - -import { runBenchmark, ARRAY_ITEMS } from "../run"; +import { ARRAY_ITEMS, runBenchmark } from "../run"; const SampleObjectType: GraphQLObjectType = new GraphQLObjectType({ name: "SampleObject", diff --git a/benchmarks/array/run.ts b/benchmarks/array/run.ts index d9e70a115..6860744b8 100644 --- a/benchmarks/array/run.ts +++ b/benchmarks/array/run.ts @@ -1,5 +1,5 @@ -import { GraphQLSchema, execute } from "graphql"; -import { gql } from "apollo-server"; +import { type GraphQLSchema, execute } from "graphql"; +import { gql } from "graphql-tag"; const BENCHMARK_ITERATIONS = 50; export const ARRAY_ITEMS = 25000; @@ -20,15 +20,16 @@ export async function runBenchmark(schema: GraphQLSchema) { } `; console.time("multipleNestedObjects"); - for (let i = 0; i < BENCHMARK_ITERATIONS; i++) { + for (let i = 0; i < BENCHMARK_ITERATIONS; i += 1) { + // eslint-disable-next-line no-await-in-loop const result = await execute({ schema, document: multipleNestedObjectsQuery }); console.assert(result.data !== undefined, "result data is undefined"); console.assert( - result.data!.multipleNestedObjects.length === ARRAY_ITEMS, + (result.data?.multipleNestedObjects as unknown[]).length === ARRAY_ITEMS, "result data is not a proper array", ); console.assert( - result.data!.multipleNestedObjects[0].nestedField.booleanField === true, + (result.data?.multipleNestedObjects as any[])[0].nestedField.booleanField === true, "data nestedField are incorrect", ); } diff --git a/benchmarks/array/type-graphql/async-field-resolvers.ts b/benchmarks/array/type-graphql/async-field-resolvers.ts index e69011b7a..732159e6b 100644 --- a/benchmarks/array/type-graphql/async-field-resolvers.ts +++ b/benchmarks/array/type-graphql/async-field-resolvers.ts @@ -1,23 +1,22 @@ import "reflect-metadata"; import { - buildSchema, Field, + FieldResolver, + Int, ObjectType, - Resolver, Query, - Int, - FieldResolver, + Resolver, Root, -} from "../../../build/package/dist"; - -import { runBenchmark, ARRAY_ITEMS } from "../run"; + buildSchema, +} from "type-graphql"; +import { ARRAY_ITEMS, runBenchmark } from "../run"; @ObjectType() class SampleObject { @Field() stringField!: string; - @Field(type => Int) + @Field(() => Int) numberField!: number; @Field() @@ -29,7 +28,7 @@ class SampleObject { @Resolver(SampleObject) class SampleResolver { - @Query(returns => [SampleObject]) + @Query(() => [SampleObject]) multipleNestedObjects(): SampleObject[] { return Array.from( { length: ARRAY_ITEMS }, diff --git a/benchmarks/array/type-graphql/simple-resolvers.ts b/benchmarks/array/type-graphql/simple-resolvers.ts index f2a97750d..9882b9df1 100644 --- a/benchmarks/array/type-graphql/simple-resolvers.ts +++ b/benchmarks/array/type-graphql/simple-resolvers.ts @@ -1,22 +1,21 @@ import "reflect-metadata"; import { - buildSchema, Field, + Int, + type MiddlewareFn, ObjectType, - Resolver, Query, - Int, - MiddlewareFn, -} from "../../../build/package/dist"; - -import { runBenchmark, ARRAY_ITEMS } from "../run"; + Resolver, + buildSchema, +} from "type-graphql"; +import { ARRAY_ITEMS, runBenchmark } from "../run"; @ObjectType({ simpleResolvers: true }) class SampleObject { @Field() stringField!: string; - @Field(type => Int) + @Field(() => Int) numberField!: number; @Field() @@ -28,7 +27,7 @@ class SampleObject { @Resolver() class SampleResolver { - @Query(returns => [SampleObject]) + @Query(() => [SampleObject]) multipleNestedObjects(): SampleObject[] { return Array.from( { length: ARRAY_ITEMS }, @@ -46,7 +45,7 @@ class SampleResolver { } } -const log = (...args: any[]) => void 0; // noop +const log = (..._: unknown[]) => undefined; // noop const loggingMiddleware: MiddlewareFn = ({ info }, next) => { log(`${info.parentType.name}.${info.fieldName} accessed`); diff --git a/benchmarks/array/type-graphql/standard.ts b/benchmarks/array/type-graphql/standard.ts index 36d5fbb9c..994875b4d 100644 --- a/benchmarks/array/type-graphql/standard.ts +++ b/benchmarks/array/type-graphql/standard.ts @@ -1,14 +1,13 @@ import "reflect-metadata"; -import { buildSchema, Field, ObjectType, Resolver, Query, Int } from "../../../build/package/dist"; - -import { runBenchmark, ARRAY_ITEMS } from "../run"; +import { Field, Int, ObjectType, Query, Resolver, buildSchema } from "type-graphql"; +import { ARRAY_ITEMS, runBenchmark } from "../run"; @ObjectType() class SampleObject { @Field() stringField!: string; - @Field(type => Int) + @Field(() => Int) numberField!: number; @Field() @@ -20,7 +19,7 @@ class SampleObject { @Resolver() class SampleResolver { - @Query(returns => [SampleObject]) + @Query(() => [SampleObject]) multipleNestedObjects(): SampleObject[] { return Array.from( { length: ARRAY_ITEMS }, diff --git a/benchmarks/array/type-graphql/sync-field-resolvers.ts b/benchmarks/array/type-graphql/sync-field-resolvers.ts index 1c9cc6e16..4c9bf3b69 100644 --- a/benchmarks/array/type-graphql/sync-field-resolvers.ts +++ b/benchmarks/array/type-graphql/sync-field-resolvers.ts @@ -1,23 +1,22 @@ import "reflect-metadata"; import { - buildSchema, Field, + FieldResolver, + Int, ObjectType, - Resolver, Query, - Int, - FieldResolver, + Resolver, Root, -} from "../../../build/package/dist"; - -import { runBenchmark, ARRAY_ITEMS } from "../run"; + buildSchema, +} from "type-graphql"; +import { ARRAY_ITEMS, runBenchmark } from "../run"; @ObjectType() class SampleObject { @Field() stringField!: string; - @Field(type => Int) + @Field(() => Int) numberField!: number; @Field() @@ -29,7 +28,7 @@ class SampleObject { @Resolver(SampleObject) class SampleResolver { - @Query(returns => [SampleObject]) + @Query(() => [SampleObject]) multipleNestedObjects(): SampleObject[] { return Array.from( { length: ARRAY_ITEMS }, diff --git a/benchmarks/array/type-graphql/sync-getters.ts b/benchmarks/array/type-graphql/sync-getters.ts index 3f9d6e19f..d8190f813 100644 --- a/benchmarks/array/type-graphql/sync-getters.ts +++ b/benchmarks/array/type-graphql/sync-getters.ts @@ -1,30 +1,33 @@ import "reflect-metadata"; -import { buildSchema, Field, ObjectType, Resolver, Query, Int } from "../../../build/package/dist"; - -import { runBenchmark, ARRAY_ITEMS } from "../run"; +import { Field, Int, ObjectType, Query, Resolver, buildSchema } from "type-graphql"; +import { ARRAY_ITEMS, runBenchmark } from "../run"; @ObjectType() class SampleObject { stringField!: string; + @Field({ name: "stringField" }) get getStringField(): string { return this.stringField; } numberField!: number; - @Field(type => Int, { name: "numberField" }) + + @Field(() => Int, { name: "numberField" }) get getNumberField(): number { return this.numberField; } booleanField!: boolean; + @Field({ name: "booleanField" }) get getBooleanField(): boolean { return this.booleanField; } nestedField?: SampleObject; - @Field(type => SampleObject, { name: "nestedField", nullable: true }) + + @Field(() => SampleObject, { name: "nestedField", nullable: true }) get getNestedField(): SampleObject | undefined { return this.nestedField; } @@ -32,7 +35,7 @@ class SampleObject { @Resolver(SampleObject) class SampleResolver { - @Query(returns => [SampleObject]) + @Query(() => [SampleObject]) multipleNestedObjects(): SampleObject[] { return Array.from( { length: ARRAY_ITEMS }, @@ -46,7 +49,7 @@ class SampleResolver { booleanField: true, numberField: index, } as SampleObject, - } as SampleObject), + }) as SampleObject, ); } } diff --git a/benchmarks/array/type-graphql/with-global-middleware.ts b/benchmarks/array/type-graphql/with-global-middleware.ts index 2b63a22dc..cdb3e87d6 100644 --- a/benchmarks/array/type-graphql/with-global-middleware.ts +++ b/benchmarks/array/type-graphql/with-global-middleware.ts @@ -1,22 +1,21 @@ import "reflect-metadata"; import { - buildSchema, Field, + Int, + type MiddlewareFn, ObjectType, - Resolver, Query, - Int, - MiddlewareFn, -} from "../../../build/package/dist"; - -import { runBenchmark, ARRAY_ITEMS } from "../run"; + Resolver, + buildSchema, +} from "type-graphql"; +import { ARRAY_ITEMS, runBenchmark } from "../run"; @ObjectType() class SampleObject { @Field() stringField!: string; - @Field(type => Int) + @Field(() => Int) numberField!: number; @Field() @@ -28,7 +27,7 @@ class SampleObject { @Resolver() class SampleResolver { - @Query(returns => [SampleObject]) + @Query(() => [SampleObject]) multipleNestedObjects(): SampleObject[] { return Array.from( { length: ARRAY_ITEMS }, @@ -46,7 +45,7 @@ class SampleResolver { } } -const log = (...args: any[]) => void 0; // noop +const log = (..._: unknown[]) => undefined; // noop const loggingMiddleware: MiddlewareFn = ({ info }, next) => { log(`${info.parentType.name}.${info.fieldName} accessed`); diff --git a/benchmarks/simple/graphql-js.ts b/benchmarks/simple/graphql-js.ts index f52cb81bd..c11039420 100644 --- a/benchmarks/simple/graphql-js.ts +++ b/benchmarks/simple/graphql-js.ts @@ -1,5 +1,4 @@ -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; - +import { GraphQLObjectType, GraphQLSchema, GraphQLString } from "graphql"; import { runBenchmark } from "./run"; const SampleObject: GraphQLObjectType = new GraphQLObjectType({ diff --git a/benchmarks/simple/run.ts b/benchmarks/simple/run.ts index 0a0cf23c5..16bfaa071 100644 --- a/benchmarks/simple/run.ts +++ b/benchmarks/simple/run.ts @@ -1,5 +1,5 @@ -import { GraphQLSchema, execute } from "graphql"; -import { gql } from "apollo-server"; +import { type ExecutionResult, type GraphQLSchema, execute } from "graphql"; +import { gql } from "graphql-tag"; const BENCHMARK_ITERATIONS = 100000; @@ -12,10 +12,11 @@ export async function runBenchmark(schema: GraphQLSchema) { } `; console.time("singleObject"); - for (let i = 0; i < BENCHMARK_ITERATIONS; i++) { - const result = await execute({ schema, document: singleObjectQuery }); + for (let i = 0; i < BENCHMARK_ITERATIONS; i += 1) { + // eslint-disable-next-line no-await-in-loop + const result: ExecutionResult = await execute({ schema, document: singleObjectQuery }); console.assert(result.data !== undefined, "result data is undefined"); - console.assert(result.data!.singleObject !== undefined, "data singleObject is undefined"); + console.assert(result.data?.singleObject !== undefined, "data singleObject is undefined"); } console.timeEnd("singleObject"); @@ -39,11 +40,12 @@ export async function runBenchmark(schema: GraphQLSchema) { } `; console.time("nestedObject"); - for (let i = 0; i < BENCHMARK_ITERATIONS; i++) { - const result = await execute({ schema, document: nestedObjectQuery }); + for (let i = 0; i < BENCHMARK_ITERATIONS; i += 1) { + // eslint-disable-next-line no-await-in-loop + const result: ExecutionResult = await execute({ schema, document: nestedObjectQuery }); console.assert(result.data !== undefined, "result data is undefined"); console.assert( - result.data!.nestedObject.nestedField.nestedField.nestedField.nestedField.sampleField !== + result.data.nestedObject.nestedField.nestedField.nestedField.nestedField.sampleField !== undefined, "data nestedField are incorrect", ); diff --git a/benchmarks/simple/type-graphql.ts b/benchmarks/simple/type-graphql.ts index 85aafda5d..2bbef1694 100644 --- a/benchmarks/simple/type-graphql.ts +++ b/benchmarks/simple/type-graphql.ts @@ -1,6 +1,5 @@ import "reflect-metadata"; -import { buildSchema, Field, ObjectType, Resolver, Query } from "../../build/package"; - +import { Field, ObjectType, Query, Resolver, buildSchema } from "type-graphql"; import { runBenchmark } from "./run"; @ObjectType() diff --git a/benchmarks/tsconfig.json b/benchmarks/tsconfig.json index 3845ce309..22878550b 100644 --- a/benchmarks/tsconfig.json +++ b/benchmarks/tsconfig.json @@ -1,12 +1,7 @@ { + "extends": "../tsconfig.json", "compilerOptions": { - "target": "es2018", - "module": "commonjs", - "lib": ["es2018"], - "strict": true, - "moduleResolution": "node", - "esModuleInterop": true, - "experimentalDecorators": true, - "emitDecoratorMetadata": true - } + "outDir": "./build" + }, + "include": [".", "../src"] } diff --git a/cspell.json b/cspell.json new file mode 100644 index 000000000..b8c013c98 --- /dev/null +++ b/cspell.json @@ -0,0 +1,72 @@ +{ + "version": "0.2", + "language": "en", + "useGitignore": true, + "import": [ + "@cspell/dict-node/cspell-ext.json", + "@cspell/dict-npm/cspell-ext.json", + "@cspell/dict-shell/cspell-ext.json", + "@cspell/dict-typescript/cspell-ext.json" + ], + "ignorePaths": [ + "**/build/", + "**/dist/", + "**/coverage/", + "**/node_modules/", + "**/package.json", + "./images/**/*.svg", + // FIXME: Remove + "website/", + "examples" + ], + "words": [ + "amet", + "argumented", + "asynciterable", + "authed", + "awad", + "casinodeps", + "cdpath", + "codecov", + "codegen", + "codeql", + "gamstop", + "graphiql", + "graphqlgen", + "graphqlid", + "graphqlisodate", + "graphqlisodatetime", + "instanceof", + "instinctools", + "inversifyjs", + "isodate", + "joiful", + "lifex", + "lovd", + "lytek", + "michaΕ‚", + "middlewares", + "mikroorm", + "nestjs", + "netrc", + "nongamstopbets", + "opencollective", + "overfetching", + "paramtypes", + "postbuild", + "realpath", + "returntype", + "shellcheck", + "sindresorhus", + "sponsorkit", + "supergraph", + "todos", + "typedefs", + "typedi", + "typegql", + "typegraphql", + "typeof", + "typeorm", + "underfetching" + ] +} diff --git a/docs/README.md b/docs/README.md index 5db924514..140d02db6 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,4 +1,3 @@ # Documentation -**The documentation has been moved to [TypeGraphQL website](https://typegraphql.com), please update your bookmarks!** -https://typegraphql.com/docs/introduction.html +**The documentation has been prepared to be viewed on [TypeGraphQL website](https://typegraphql.com), please read it there.** diff --git a/docs/authorization.md b/docs/authorization.md index a90a6bb1c..d3bd573fe 100644 --- a/docs/authorization.md +++ b/docs/authorization.md @@ -13,7 +13,7 @@ That's why authorization is a first-class feature in `TypeGraphQL`! First, we need to use the `@Authorized` decorator as a guard on a field, query or mutation. Example object type field guards: -```typescript +```ts @ObjectType() class MyObject { @Field() @@ -40,7 +40,7 @@ Thus, authorized users (regardless of their roles) can only read the `publicFiel Sample query and mutation guards: -```typescript +```ts @Resolver() class MyResolver { @Query() @@ -70,16 +70,16 @@ Authorized users (regardless of their roles) will be able to read data from the Next, we need to create our auth checker function. Its implementation may depend on our business logic: -```typescript +```ts export const customAuthChecker: AuthChecker = ( { root, args, context, info }, roles, ) => { - // here we can read the user from context - // and check his permission in the db against the `roles` argument - // that comes from the `@Authorized` decorator, eg. ["ADMIN", "MODERATOR"] + // Read user from context + // and check the user's permission against the `roles` argument + // that comes from the '@Authorized' decorator, eg. ["ADMIN", "MODERATOR"] - return true; // or false if access is denied + return true; // or 'false' if access is denied }; ``` @@ -89,15 +89,17 @@ Auth checker can be also defined as a class - this way we can leverage the depen ```ts export class CustomAuthChecker implements AuthCheckerInterface { - // inject dependency - constructor(private readonly userRepository: Repository) {} + constructor( + // Dependency injection + private readonly userRepository: Repository, + ) {} check({ root, args, context, info }: ResolverData, roles: string[]) { const userId = getUserIdFromToken(context.token); - // use injected service + // Use injected service const user = this.userRepository.getById(userId); - // custom logic here, e.g.: + // Custom logic, e.g.: return user % 2 === 0; } } @@ -105,12 +107,12 @@ export class CustomAuthChecker implements AuthCheckerInterface { The last step is to register the function or class while building the schema: -```typescript +```ts import { customAuthChecker } from "../auth/custom-auth-checker.ts"; const schema = await buildSchema({ resolvers: [MyResolver], - // here we register the auth checking function + // Register the auth checking function // or defining it inline authChecker: customAuthChecker, }); @@ -120,7 +122,7 @@ And it's done! πŸ˜‰ If we need silent auth guards and don't want to return authorization errors to users, we can set the `authMode` property of the `buildSchema` config object to `"null"`: -```typescript +```ts const schema = await buildSchema({ resolvers: ["./**/*.resolver.ts"], authChecker: customAuthChecker, @@ -133,46 +135,55 @@ It will then return `null` instead of throwing an authorization error. ## Recipes We can also use `TypeGraphQL` with JWT authentication. -Here's an example using `apollo-server-express`: +Here's an example using `@apollo/server`: -```typescript +```ts +import { ApolloServer } from "@apollo/server"; +import { expressMiddleware } from "@apollo/server/express4"; import express from "express"; -import { ApolloServer, gql } from "apollo-server-express"; -import * as jwt from "express-jwt"; +import jwt from "express-jwt"; +import bodyParser from "body-parser"; +import { schema } from "./graphql/schema"; +import { User } from "./User.type"; -import { schema } from "../example/above"; +// GraphQL path +const GRAPHQL_PATH = "/graphql"; + +// GraphQL context +type Context = { + user?: User; +}; +// Express const app = express(); -const path = "/graphql"; - -// Create a GraphQL server -const server = new ApolloServer({ - schema, - context: ({ req }) => { - const context = { - req, - user: req.user, // `req.user` comes from `express-jwt` - }; - return context; - }, -}); -// Mount a jwt or other authentication middleware that is run before the GraphQL execution +// Apollo server +const server = new ApolloServer({ schema }); +await server.start(); + +// Mount a JWT or other authentication middleware that is run before the GraphQL execution app.use( - path, + GRAPHQL_PATH, jwt({ secret: "TypeGraphQL", credentialsRequired: false, }), ); -// Apply the GraphQL server middleware -server.applyMiddleware({ app, path }); - -// Launch the express server -app.listen({ port: 4000 }, () => - console.log(`πŸš€ Server ready at http://localhost:4000${server.graphqlPath}`), +// Apply GraphQL server middleware +app.use( + GRAPHQL_PATH, + bodyParser.json(), + expressMiddleware(server, { + // Build context + // 'req.user' comes from 'express-jwt' + context: async ({ req }) => ({ user: req.user }), + }), ); + +// Start server +await new Promise(resolve => app.listen({ port: 4000 }, resolve)); +console.log(`GraphQL server ready at http://localhost:4000/${GRAPHQL_PATH}`); ``` Then we can use standard, token based authorization in the HTTP header like in classic REST APIs and take advantage of the `TypeGraphQL` authorization mechanism. diff --git a/docs/aws-lambda.md b/docs/aws-lambda.md new file mode 100644 index 000000000..db219f6a2 --- /dev/null +++ b/docs/aws-lambda.md @@ -0,0 +1,35 @@ +--- +title: AWS Lambda integration +--- + +## Using TypeGraphQL in AWS Lambda environment + +AWS Lambda environment is a bit different than a standard Node.js server deployment. + +However, the only tricky part with the setup is that we need to "cache" the built schema, to save some computing time by avoiding rebuilding the schema on every request to our lambda. + +So all we need to do is to assign the built schema to the local variable using the `??=` conditional assignment operator. +We can do the same thing for `ApolloServer`. + +Below you you can find the full snippet for the AWS Lambda integration: + +```ts +import { APIGatewayProxyHandlerV2 } from "aws-lambda"; +import { ApolloServer } from "apollo-server-lambda"; + +let cachedSchema: GraphQLSchema | null = null; +let cachedServer: ApolloServer | null = null; + +export const handler: APIGatewayProxyHandlerV2 = async (event, context, callback) => { + // build TypeGraphQL executable schema only once, then read it from local "cached" variable + cachedSchema ??= await buildSchema({ + resolvers: [RecipeResolver], + }); + + // create the GraphQL server only once + cachedServer ??= new ApolloServer({ schema: cachedSchema }); + + // make a handler for `aws-lambda` + return cachedServer.createHandler({})(event, context, callback); +}; +``` diff --git a/docs/bootstrap.md b/docs/bootstrap.md index 433bc003e..e06936666 100644 --- a/docs/bootstrap.md +++ b/docs/bootstrap.md @@ -9,10 +9,10 @@ After creating our resolvers, type classes, and other business-related code, we To create an executable schema from type and resolver definitions, we need to use the `buildSchema` function. It takes a configuration object as a parameter and returns a promise of a `GraphQLSchema` object. -In the configuration object we must provide a `resolvers` property, which can be an array of resolver classes: +In the configuration object we must provide a `resolvers` property, which is supposed to be an array of resolver classes: -```typescript -import { FirstResolver, SecondResolver } from "../app/src/resolvers"; +```ts +import { FirstResolver, SecondResolver } from "./resolvers"; // ... const schema = await buildSchema({ resolvers: [FirstResolver, SecondResolver], @@ -21,22 +21,22 @@ const schema = await buildSchema({ Be aware that only operations (queries, mutation, etc.) defined in the resolvers classes (and types directly connected to them) will be emitted in schema. -So if we have defined some object types (that implements an interface type [with disabled auto registering](interfaces.md#registering-in-schema)) but are not directly used in other types definition (like a part of an union, a type of a field or a return type of an operation), we need to provide them manually in `orphanedTypes` options of `buildSchema`: +So if we have defined some object types (that implements an interface type [with disabled auto registering](./interfaces.md#registering-in-schema)) but are not directly used in other types definition (like a part of an union, a type of a field or a return type of an operation), we need to provide them manually in `orphanedTypes` options of `buildSchema`: -```typescript +```ts import { FirstResolver, SecondResolver } from "../app/src/resolvers"; import { FirstObject } from "../app/src/types"; // ... const schema = await buildSchema({ resolvers: [FirstResolver, SecondResolver], - // here provide all the types that are missing in schema + // Provide all the types that are missing in schema orphanedTypes: [FirstObject], }); ``` In case of defining the resolvers array somewhere else (not inline in the `buildSchema`), we need to use the `as const` syntax to inform the TS compiler and satisfy the `NonEmptyArray` constraints: -```typescript +```ts // resolvers.ts export const resolvers = [FirstResolver, SecondResolver] as const; @@ -46,62 +46,53 @@ import { resolvers } from "./resolvers"; const schema = await buildSchema({ resolvers }); ``` -However, when there are several resolver classes, manual imports can be cumbersome. -So we can also provide an array of paths to resolver module files instead, which can include globs: - -```typescript -const schema = await buildSchema({ - resolvers: [__dirname + "/modules/**/*.resolver.{ts,js}", __dirname + "/resolvers/**/*.{ts,js}"], -}); -``` - -> Be aware that in case of providing paths to resolvers files, TypeGraphQL will emit all the operations and types that are imported in the resolvers files or their dependencies. - -There are also other options related to advanced features like [authorization](authorization.md) or [validation](validation.md) - you can read about them in docs. +There are also other options related to advanced features like [authorization](./authorization.md) or [validation](./validation.md) - you can read about them in docs. To make `await` work, we need to declare it as an async function. Example of `main.ts` file: -```typescript +```ts import { buildSchema } from "type-graphql"; async function bootstrap() { const schema = await buildSchema({ - resolvers: [__dirname + "/**/*.resolver.{ts,js}"], + resolvers: [ + // ... Resolvers classes + ], }); - // other initialization code, like creating http server + // ... } -bootstrap(); // actually run the async function +bootstrap(); // Actually run the async function ``` ## Create an HTTP GraphQL endpoint -In most cases, the GraphQL app is served by an HTTP server. After building the schema we can create the GraphQL endpoint with a variety of tools such as [`graphql-yoga`](https://github.com/prisma/graphql-yoga) or [`apollo-server`](https://github.com/apollographql/apollo-server). Here is an example using [`apollo-server`](https://github.com/apollographql/apollo-server): +In most cases, the GraphQL app is served by an HTTP server. After building the schema we can create the GraphQL endpoint with a variety of tools such as [`graphql-yoga`](https://github.com/dotansimha/graphql-yoga) or [`@apollo/server`](https://github.com/apollographql/apollo-server). -```typescript -import { ApolloServer } from "apollo-server"; +Below is an example using [`@apollo/server`](https://github.com/apollographql/apollo-server): + +```ts +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; const PORT = process.env.PORT || 4000; async function bootstrap() { - // ... Building schema here + // ... Build GraphQL schema - // Create the GraphQL server - const server = new ApolloServer({ - schema, - playground: true, - }); + // Create GraphQL server + const server = new ApolloServer({ schema }); - // Start the server - const { url } = await server.listen(PORT); - console.log(`Server is running, GraphQL Playground available at ${url}`); + // Start server + const { url } = await startStandaloneServer(server, { listen: { port: 4000 } }); + console.log(`GraphQL server ready at ${url}`); } bootstrap(); ``` -Remember to install the `apollo-server` package from npm - it's not bundled with TypeGraphQL. +Remember to install the `@apollo/server` package from npm - it's not bundled with TypeGraphQL. Of course you can use the `express-graphql` middleware, `graphql-yoga` or whatever you want πŸ˜‰ @@ -109,10 +100,10 @@ Of course you can use the `express-graphql` middleware, `graphql-yoga` or whatev TypeGraphQL provides a second way to generate the GraphQL schema - the `buildTypeDefsAndResolvers` function. -It accepts the same `BuildSchemaOptions` as the `buildSchema` function but instead of an executable `GraphQLSchema`, it creates a typeDefs and resolversMap pair that you can use e.g. with [`graphql-tools`](https://github.com/apollographql/graphql-tools): +It accepts the same `BuildSchemaOptions` as the `buildSchema` function but instead of an executable `GraphQLSchema`, it creates a typeDefs and resolversMap pair that you can use e.g. with [@graphql-tools/\*`](https://the-guild.dev/graphql/tools): -```typescript -import { makeExecutableSchema } from "graphql-tools"; +```ts +import { makeExecutableSchema } from "@graphql-tools/schema"; const { typeDefs, resolvers } = await buildTypeDefsAndResolvers({ resolvers: [FirstResolver, SecondResolver], @@ -123,7 +114,7 @@ const schema = makeExecutableSchema({ typeDefs, resolvers }); Or even with other libraries that expect the schema info in that shape, like [`apollo-link-state`](https://github.com/apollographql/apollo-link-state): -```typescript +```ts import { withClientState } from "apollo-link-state"; const { typeDefs, resolvers } = await buildTypeDefsAndResolvers({ @@ -131,20 +122,20 @@ const { typeDefs, resolvers } = await buildTypeDefsAndResolvers({ }); const stateLink = withClientState({ - // ...other options like `cache` + // ... Other options like `cache` typeDefs, resolvers, }); -// ...the rest of `ApolloClient` initialization code +// ... Rest of `ApolloClient` initialization code ``` -There's also a sync version of it - `buildTypeDefsAndResolversSync`: +There's also a `sync` version of it - `buildTypeDefsAndResolversSync`: -```typescript -const { typeDefs, resolvers } = buildTypeDefsAndResolvers({ +```ts +const { typeDefs, resolvers } = buildTypeDefsAndResolversSync({ resolvers: [FirstResolver, SecondResolver], }); ``` -However, be aware that some of the TypeGraphQL features (i.a. [query complexity](complexity.md)) might not work with the `buildTypeDefsAndResolvers` approach because they use some low-level `graphql-js` features. +However, be aware that some of the TypeGraphQL features (i.a. [query complexity](./complexity.md)) might not work with the `buildTypeDefsAndResolvers` approach because they use some low-level `graphql-js` features. diff --git a/docs/browser-usage.md b/docs/browser-usage.md index a1eb733d9..7429b3959 100644 --- a/docs/browser-usage.md +++ b/docs/browser-usage.md @@ -6,33 +6,59 @@ title: Browser usage Sometimes we might want to use the classes we've created and annotated with TypeGraphQL decorators, in our client app that works in the browser. For example, reusing the args or input classes with `class-validator` decorators or the object type classes with some helpful custom methods. -Since TypeGraphQL is a Node.js framework, it doesn't work in a browser environment, so we may quickly get an error, e.g. `ERROR in ./node_modules/fs.realpath/index.js` or `utils1_promisify is not a function`, while trying to build our app with Webpack. To correct this, we have to configure Webpack to use the decorator shim instead of the normal module. We simply add this plugin code to our webpack config: +Since TypeGraphQL is a Node.js framework, it doesn't work in a browser environment, so we may quickly get an error, e.g. `ERROR in ./node_modules/fs.realpath/index.js` or `utils1_promisify is not a function`, while trying to build our app e.g. with Webpack. To correct this, we have to configure bundler or compiler to use the decorator shim instead of the normal module. + +The steps to accomplish this are different, depending on the framework, bundler or compiler we use. +However, in all cases, using shim makes our bundle much lighter as we don't need to embed the whole TypeGraphQL library code in our app. + +## CRA and similar + +We simply add this plugin code to our webpack config: ```js module.exports = { - // ... the rest of the webpack config + // ... Rest of Webpack configuration plugins: [ - // ... here are any other existing plugins that we already have + // ... Other existing plugins new webpack.NormalModuleReplacementPlugin(/type-graphql$/, resource => { - resource.request = resource.request.replace(/type-graphql/, "type-graphql/dist/browser-shim.js"); + resource.request = resource.request.replace(/type-graphql/, "type-graphql/shim"); }), ]; } ``` -In case of cypress, you can adapt the same webpack config trick just by applying the [cypress-webpack-preprocessor](https://github.com/cypress-io/cypress-webpack-preprocessor) plugin. +In case of cypress, we can adapt the same webpack config trick just by applying the [cypress-webpack-preprocessor](https://github.com/cypress-io/cypress-webpack-preprocessor) plugin. + +## Angular and similar + +In some TypeScript projects, like the ones using Angular, which AoT compiler requires that a full `*.ts` file is provided instead of just a `*.js` and `*.d.ts` files, to use this shim we have to simply set up our TypeScript configuration in `tsconfig.json` to use this file instead of a normal TypeGraphQL module: + +```json +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "type-graphql": ["node_modules/type-graphql/build/typings/shim.ts"] + } + } +} +``` + +## Next.js and similar + +When using the shim with Next.js as a dedicated frontend server be aware that Next has pre-renders on the server. This means that in development mode the `webpack: {}` config in `next.config.js` is skipped and full `type-graphql` is bundled. But we still need to handle some webpack rewiring for the client bundling which still happens with webpack both in development and in production mode. -However, in some TypeScript projects like the ones using Angular, which AoT compiler requires that a full `*.ts` file is provided instead of just a `*.js` and `*.d.ts` files, to use this shim we have to simply set up our TypeScript configuration in `tsconfig.json` to use this file instead of a normal TypeGraphQL module: +The easiest way is to accomplish this is also done in `tsconfig.json` - add the same keys like in the example before to `compilerOptions`: ```json { "compilerOptions": { "baseUrl": ".", "paths": { - "type-graphql": ["./node_modules/type-graphql/dist/browser-shim.ts"] + "type-graphql": ["node_modules/type-graphql/build/typings/shim.ts"] } } } ``` -Thanks to this, our bundle will be much lighter as we don't need to embed the whole TypeGraphQL library code in our app. +Then, `npm install -D tsconfig-paths` and enable it with `NODE_OPTIONS="-r tsconfig-paths/register"` in our environment variables setup. diff --git a/docs/complexity.md b/docs/complexity.md index b0ec11d8a..c789e608a 100644 --- a/docs/complexity.md +++ b/docs/complexity.md @@ -14,7 +14,7 @@ First, we need to pass `complexity` as an option to the decorator on a field, qu Example of complexity -```typescript +```ts @ObjectType() class MyObject { @Field({ complexity: 2 }) @@ -31,54 +31,54 @@ Complexity can be passed as an option to any `@Field`, `@FieldResolver`, `@Mutat In the next step, we will integrate `graphql-query-complexity` with the server that expose our GraphQL schema over HTTP. You can use it with `express-graphql` like [in the lib examples](https://github.com/slicknode/graphql-query-complexity/blob/b6a000c0984f7391f3b4e886e3df6a7ed1093b07/README.md#usage-with-express-graphql), however we will use Apollo Server like in our other examples: -```typescript +```ts async function bootstrap() { - // ...build TypeGraphQL schema as always + // ... Build GraphQL schema // Create GraphQL server const server = new ApolloServer({ schema, - // Create a plugin that will allow for query complexity calculation for every request + // Create a plugin to allow query complexity calculation for every request plugins: [ { - requestDidStart: () => ({ - didResolveOperation({ request, document }) { + requestDidStart: async () => ({ + async didResolveOperation({ request, document }) { /** - * This provides GraphQL query analysis to be able to react on complex queries to your GraphQL server. - * This can be used to protect your GraphQL servers against resource exhaustion and DoS attacks. - * More documentation can be found at https://github.com/ivome/graphql-query-complexity. + * Provides GraphQL query analysis to be able to react on complex queries to the GraphQL server + * It can be used to protect the GraphQL server against resource exhaustion and DoS attacks + * More documentation can be found at https://github.com/ivome/graphql-query-complexity */ const complexity = getComplexity({ - // Our built schema + // GraphQL schema schema, // To calculate query complexity properly, - // we have to check only the requested operation + // check only the requested operation // not the whole document that may contains multiple operations operationName: request.operationName, - // The GraphQL query document + // GraphQL query document query: document, - // The variables for our GraphQL query + // GraphQL query variables variables: request.variables, // Add any number of estimators. The estimators are invoked in order, the first - // numeric value that is being returned by an estimator is used as the field complexity. - // If no estimator returns a value, an exception is raised. + // numeric value that is being returned by an estimator is used as the field complexity + // If no estimator returns a value, an exception is raised estimators: [ - // Using fieldExtensionsEstimator is mandatory to make it work with type-graphql. + // Using fieldExtensionsEstimator is mandatory to make it work with type-graphql fieldExtensionsEstimator(), // Add more estimators here... // This will assign each field a complexity of 1 - // if no other estimator returned a value. + // if no other estimator returned a value simpleEstimator({ defaultComplexity: 1 }), ], }); - // Here we can react to the calculated complexity, - // like compare it with max and throw error when the threshold is reached. - if (complexity > 20) { + + // React to the calculated complexity, + // like compare it with max and throw error when the threshold is reached + if (complexity > MAX_COMPLEXITY) { throw new Error( - `Sorry, too complicated query! ${complexity} is over 20 that is the max allowed complexity.`, + `Sorry, too complicated query! ${complexity} exceeded the maximum allowed complexity of ${MAX_COMPLEXITY}`, ); } - // And here we can e.g. subtract the complexity point from hourly API calls limit. console.log("Used query complexity points:", complexity); }, }), @@ -86,7 +86,9 @@ async function bootstrap() { ], }); - // ...start the server as always + // Start server + const { url } = await startStandaloneServer(server, { listen: { port: 4000 } }); + console.log(`GraphQL server ready at ${url}`); } ``` diff --git a/docs/custom-decorators.md b/docs/custom-decorators.md index 54e70f4b6..9f3992258 100644 --- a/docs/custom-decorators.md +++ b/docs/custom-decorators.md @@ -6,16 +6,16 @@ Custom decorators are a great way to reduce the boilerplate and reuse some commo ## Method decorators -Using [middlewares](middlewares.md) allows to reuse some code between resolvers. To further reduce the boilerplate and have a nicer API, we can create our own custom method decorators. +Using [middlewares](./middlewares.md) allows to reuse some code between resolvers. To further reduce the boilerplate and have a nicer API, we can create our own custom method decorators. -They work in the same way as the [reusable middleware function](middlewares.md#reusable-middleware), however, in this case we need to call `createMethodDecorator` helper function with our middleware logic and return its value: +They work in the same way as the [reusable middleware function](./middlewares.md#reusable-middleware), however, in this case we need to call `createMethodDecorator` helper function with our middleware logic and return its value: -```typescript +```ts export function ValidateArgs(schema: JoiSchema) { return createMethodDecorator(async ({ args }, next) => { - // here place your middleware code that uses custom decorator arguments + // Middleware code that uses custom decorator arguments - // e.g. validation logic based on schema using joi + // e.g. Validation logic based on schema using 'joi' await joiValidate(schema, args); return next(); }); @@ -24,11 +24,11 @@ export function ValidateArgs(schema: JoiSchema) { The usage is then very simple, as we have a custom, descriptive decorator - we just place it above the resolver/field and pass the required arguments to it: -```typescript +```ts @Resolver() export class RecipeResolver { - @ValidateArgs(MyArgsSchema) // custom decorator - @UseMiddleware(ResolveTime) // explicit middleware + @ValidateArgs(MyArgsSchema) // Custom decorator + @UseMiddleware(ResolveTime) // Explicit middleware @Query() randomValue(@Args() { scale }: MyArgs): number { return Math.random() * scale; @@ -42,28 +42,31 @@ Parameter decorators are just like the custom method decorators or middlewares b They might be just a simple data extractor function, that makes our resolver more unit test friendly: -```typescript +```ts function CurrentUser() { return createParamDecorator(({ context }) => context.currentUser); } ``` -Or might be a more advanced one that performs some calculations and encapsulates some logic. Compared to middlewares, they allows for a more granular control on executing the code, like calculating fields map based on GraphQL info only when it's really needed (requested by using the `@Fields()` decorator): +Or might be a more advanced one that performs some calculations and encapsulates some logic. Compared to middlewares, they allow for a more granular control on executing the code, like calculating fields map based on GraphQL info only when it's really needed (requested by using the `@Fields()` decorator): -```typescript +```ts function Fields(level = 1): ParameterDecorator { - return createParamDecorator(({ info }) => { + return createParamDecorator(async ({ info }) => { const fieldsMap: FieldsMap = {}; - // calculate an object with info about requested fields - // based on GraphQL `info` parameter of the resolver and the level parameter + // Calculate an object with info about requested fields + // based on GraphQL 'info' parameter of the resolver and the level parameter + // or even call some async service, as it can be a regular async function and we can just 'await' return fieldsMap; }); } ``` +> Be aware, that `async` function as a custom param decorators logic can make the GraphQL resolver execution slower, so try to avoid them, if possible. + Then we can use our custom param decorators in the resolvers just like the built-in decorators: -```typescript +```ts @Resolver() export class RecipeResolver { constructor(private readonly recipesRepository: Repository) {} @@ -72,23 +75,23 @@ export class RecipeResolver { @Mutation(returns => Recipe) async addRecipe( @Args() recipeData: AddRecipeInput, - // here we place our custom decorator - // just like the built-in one + // Custom decorator just like the built-in one @CurrentUser() currentUser: User, ) { const recipe: Recipe = { ...recipeData, - // and use the data returned from custom decorator in our resolver code + // and use the data returned from custom decorator in the resolver code author: currentUser, }; await this.recipesRepository.save(recipe); + return recipe; } @Query(returns => Recipe, { nullable: true }) async recipe( @Arg("id") id: string, - // our custom decorator that parses the fields from graphql query info + // Custom decorator that parses the fields from GraphQL query info @Fields() fields: FieldsMap, ) { return await this.recipesRepository.find(id, { diff --git a/docs/dependency-injection.md b/docs/dependency-injection.md index 2ded05ba6..c22208f31 100644 --- a/docs/dependency-injection.md +++ b/docs/dependency-injection.md @@ -12,37 +12,37 @@ The usage of this feature is very simple - all you need to do is register a 3rd Example using TypeDI: -```typescript +```ts import { buildSchema } from "type-graphql"; -// import your IoC container +// IOC container import { Container } from "typedi"; - import { SampleResolver } from "./resolvers"; -// build the schema as always +// Build TypeGraphQL executable schema const schema = await buildSchema({ + // Array of resolvers resolvers: [SampleResolver], - // register the 3rd party IOC container + // Registry 3rd party IOC container container: Container, }); ``` -Our resolvers will then be able to declare their dependencies and TypeGraphQL will use the container to solve them: +Resolvers will then be able to declare their dependencies and TypeGraphQL will use the container to solve them: -```typescript +```ts import { Service } from "typedi"; @Service() @Resolver(of => Recipe) export class RecipeResolver { constructor( - // constructor injection of a service + // Dependency injection private readonly recipeService: RecipeService, ) {} @Query(returns => Recipe, { nullable: true }) async recipe(@Arg("recipeId") recipeId: string) { - // usage of the injected service + // Usage of the injected service return this.recipeService.getOne(recipeId); } } @@ -50,7 +50,7 @@ export class RecipeResolver { A sample recipe service implementation may look like this: -```typescript +```ts import { Service, Inject } from "typedi"; @Service() @@ -70,7 +70,7 @@ export class RecipeService { > Be aware than when you use [InversifyJS](https://github.com/inversify/InversifyJS), you have to bind the resolver class with the [self-binding of concrete types](https://github.com/inversify/InversifyJS/blob/master/wiki/classes_as_id.md#self-binding-of-concrete-types), e.g.: > -> ```typescript +> ```ts > container.bind(SampleResolver).to(SampleResolver).inSingletonScope(); > ``` @@ -83,61 +83,79 @@ First we need to provide a container resolver function. It takes the resolver da For simple container libraries we may define it inline, e.g. using `TypeDI`: -```typescript +```ts await buildSchema({ container: (({ context }: ResolverData) => Container.of(context.requestId)); }; ``` -The tricky part is where the `context.requestId` comes from. Unfortunately, we need to provide it manually using hooks that are exposed by HTTP GraphQL middleware like `express-graphql`, `apollo-server` or `graphql-yoga`. +The tricky part is where the `context.requestId` comes from. Unfortunately, we need to provide it manually using hooks that are exposed by HTTP GraphQL middleware like `express-graphql`, `@apollo/server` or `graphql-yoga`. For some other advanced libraries, we might need to create an instance of the container, place it in the context object and then retrieve it in the `container` getter function: -```typescript +```ts await buildSchema({ container: (({ context }: ResolverData) => context.container); }; ``` -Example using `TypeDI` and `apollo-server` with the `context` creation method: +Example using `TypeDI` and `@apollo/server` with the `context` creation method: -```typescript -import { ApolloServer } from "apollo-server"; +```ts +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; import { Container } from "typedi"; +// Create GraphQL server const server = new ApolloServer({ - // schema comes from `buildSchema` as always + // GraphQL schema schema, - // provide unique context with `requestId` for each request - context: () => { - // generate the requestId (it also may come from `express-request-id` or other middleware) +}); + +// Start server +const { url } = await startStandaloneServer(server, { + listen: { port: 4000 }, + // Provide unique context with 'requestId' for each request + context: async () => { const requestId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // uuid-like - const container = Container.of(requestId); // get the scoped container - const context = { requestId, container }; // create fresh context object - container.set("context", context); // place context or other data in container + const container = Container.of(requestId.toString()); // Get scoped container + const context = { requestId, container }; // Create context + container.set("context", context); // Set context or other data in container + return context; }, }); +console.log(`GraphQL server ready at ${url}`); ``` We also have to dispose the container after the request has been handled and the response is ready. Otherwise, there would be a huge memory leak as the new instances of services and resolvers have been created for each request but they haven't been cleaned up. -Apollo Server since version 2.2.0 has a [plugins](https://www.apollographql.com/docs/apollo-server/integrations/plugins/) feature that supports [`willSendResponse`](https://www.apollographql.com/docs/apollo-server/integrations/plugins/#willsendresponse) lifecycle event. We can leverage it to clean up the container after handling the request. +Apollo Server has a [plugins](https://www.apollographql.com/docs/apollo-server/integrations/plugins) feature that supports [`willSendResponse`](https://www.apollographql.com/docs/apollo-server/integrations/plugins/#willsendresponse) lifecycle event. We can leverage it to clean up the container after handling the request. -Example using `TypeDI` and `apollo-server` with plugins approach: +Example using `TypeDI` and `@apollo/server` with plugins approach: -```typescript -import { ApolloServer } from "apollo-server"; +```ts +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; import { Container } from "typedi"; const server = new ApolloServer({ - // ... schema and context here + // GraphQL schema + schema, + // Create a plugin to allow for disposing the scoped container created for every request plugins: [ { - requestDidStart: () => ({ - willSendResponse(requestContext) { - // remember to dispose the scoped container to prevent memory leaks - Container.reset(requestContext.context.requestId); + requestDidStart: async () => ({ + async willSendResponse(requestContext) { + // Dispose the scoped container to prevent memory leaks + Container.reset(requestContext.contextValue.requestId.toString()); + + // For developers curiosity purpose, here is the logging of current scoped container instances + // Make multiple parallel requests to see in console how this works + const instancesIds = ((Container as any).instances as ContainerInstance[]).map( + instance => instance.id, + ); + console.log("Instances left in memory: ", instancesIds); }, }), }, @@ -156,3 +174,5 @@ The only thing that's left is the container configuration - we need to check out You can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/master/examples/using-container). For a more advanced usage example with scoped containers, check out [advanced example with scoped containers](https://github.com/MichalLytek/type-graphql/tree/master/examples/using-scoped-container). + +Integration with [TSyringe](https://github.com/MichalLytek/type-graphql/tree/master/examples/tsyringe). diff --git a/docs/directives.md b/docs/directives.md index 775de64da..92fde46a5 100644 --- a/docs/directives.md +++ b/docs/directives.md @@ -2,9 +2,9 @@ title: Directives --- -> A directive is an identifier preceded by a @ character, optionally followed by a list of named arguments, which can appear after almost any form of syntax in the GraphQL query or schema languages. +> A directive is an identifier preceded by a `@` character, optionally followed by a list of named arguments, which can appear after almost any form of syntax in the GraphQL query or schema languages. -Though the [GraphQL directives](https://www.apollographql.com/docs/graphql-tools/schema-directives/) syntax is similar to TS decorators, they are purely an SDL (Schema Definition Language) feature that allows you to add metadata to a selected type or its field: +Though the [GraphQL directives](https://www.apollographql.com/docs/graphql-tools/schema-directives) syntax is similar to TS decorators, they are purely an SDL (Schema Definition Language) feature that allows you to add metadata to a selected type or its field: ```graphql type Foo @auth(requires: USER) { @@ -26,15 +26,15 @@ That metadata can be read at runtime to modify the structure and behavior of a G Basically, we declare the usage of directives just like in SDL, with the `@` syntax: -```typescript +```ts @Directive('@deprecated(reason: "Use newField")') ``` -Currently, you can use the directives only on object types, input types, interface types and their fields or fields resolvers, as well as queries, mutations and subscriptions. Other locations like scalars, enums, unions or arguments are not yet supported. +Currently, you can use the directives only on object types, input types, interface types and their fields or fields resolvers, args type fields, as well as queries, mutations and subscriptions and the inline arguments. Other locations like scalars, enums or unions are not yet supported. So the `@Directive` decorator can be placed over the class property/method or over the type class itself, depending on the needs and the placements supported by the implementation: -```typescript +```ts @Directive("@auth(requires: USER)") @ObjectType() class Foo { @@ -49,11 +49,18 @@ class Bar { field: string; } +@ArgsType() +class FooBarArgs { + @Directive('@deprecated(reason: "Not used anymore")') + @Field({ nullable: true }) + baz?: string; +} + @Resolver(of => Foo) class FooBarResolver { @Directive("@auth(requires: ANY)") @Query() - foobar(@Arg("baz") baz: string): string { + foobar(@Args() { baz }: FooBarArgs): string { return "foobar"; } @@ -65,11 +72,36 @@ class FooBarResolver { } ``` -> Note that even as directives are a purely SDL thing, they won't appear in the generated schema definition file. Current implementation of directives in TypeGraphQL is using some crazy workarounds because [`graphql-js` doesn't support setting them by code](https://github.com/graphql/graphql-js/issues/1343) and the built-in `printSchema` utility omits the directives while printing. +In case of inline args using `@Arg` decorator, directives can be placed over the parameter of the class method: + +```ts +@Resolver(of => Foo) +class FooBarResolver { + @Query() + foo( + @Directive('@deprecated(reason: "Not used anymore")') + @Arg("foobar", { defaultValue: "foobar" }) + foobar: string, + ) { + return "foo"; + } + + @FieldResolver() + bar( + @Directive('@deprecated(reason: "Not used anymore")') + @Arg("foobar", { defaultValue: "foobar" }) + foobar: string, + ) { + return "bar"; + } +} +``` + +> Note that even as directives are a purely SDL thing, they won't appear in the generated schema definition file. Current implementation of directives in TypeGraphQL is using some crazy workarounds because [`graphql-js` doesn't support setting them by code](https://github.com/graphql/graphql-js/issues/1343) and the built-in `printSchema` utility omits the directives while printing. See [emit schema with custom directives](./emit-schema.md#emit-schema-with-custom-directives) for more info. Also please note that `@Directive` can only contain a single GraphQL directive name or declaration. If you need to have multiple directives declared, just place multiple decorators: -```typescript +```ts @ObjectType() class Foo { @Directive("@lowercase") @@ -84,20 +116,46 @@ class Foo { Besides declaring the usage of directives, you also have to register the runtime part of the used directives. -> Be aware that TypeGraphQL doesn't have any special way for implementing schema directives. You should use some [3rd party libraries](https://www.apollographql.com/docs/graphql-tools/schema-directives/#implementing-schema-directives) depending on the tool set you use in your project, e.g. `graphql-tools` or `ApolloServer`. +> Be aware that TypeGraphQL doesn't have any special way for implementing schema directives. You should use some [3rd party libraries](https://the-guild.dev/graphql/tools/docs/schema-directives#implementing-schema-directives) depending on the tool set you use in your project, e.g. `@graphql-tools/*` or `ApolloServer`. + +If you write your custom GraphQL directive or import a package that exports a `GraphQLDirective` instance, you need to register the directives definitions in the `buildSchema` options: -Here is an example using the [`graphql-tools`](https://github.com/apollographql/graphql-tools): +```ts +// Build TypeGraphQL executable schema +const tempSchema = await buildSchema({ + resolvers: [SampleResolver], + // Register the directives definitions + directives: [myDirective], +}); +``` -```typescript -import { SchemaDirectiveVisitor } from "graphql-tools"; +Then you need to apply the schema transformer for your directive, that implements the desired logic of your directive: -// build the schema as always -const schema = buildSchemaSync({ +```ts +// Transform and obtain the final schema +const schema = myDirectiveTransformer(tempSchema); +``` + +If the directive package used by you exports a string-based `typeDefs`, you need to add those typedefs to the schema and then apply directive transformer. + +Here is an example using the [`@graphql-tools/*`](https://the-guild.dev/graphql/tools): + +```ts +import { mergeSchemas } from "@graphql-tools/schema"; +import { renameDirective } from "fake-rename-directive-package"; + +// Build TypeGraphQL executable schema +const schemaSimple = await buildSchema({ resolvers: [SampleResolver], }); -// register the used directives implementations -SchemaDirectiveVisitor.visitSchemaDirectives(schema, { - sample: SampleDirective, +// Merge schema with sample directive type definitions +const schemaMerged = mergeSchemas({ + schemas: [schemaSimple], + // Register the directives definitions + typeDefs: [renameDirective.typeDefs], }); + +// Transform and obtain the final schema +const schema = renameDirective.transformer(schemaMerged); ``` diff --git a/docs/emit-schema.md b/docs/emit-schema.md index 80ebb97be..79675c49f 100644 --- a/docs/emit-schema.md +++ b/docs/emit-schema.md @@ -2,34 +2,34 @@ title: Emitting the schema SDL --- -TypeGraphQL's main feature is creating the schema using only TypeScript classes and decorators. However, there might be a need for the schema to be printed into a `schema.gql` file and there are plenty of reasons for that. Mainly, the schema SDL file is needed for GraphQL ecosystem tools that perform client-side queries autocompletion and validation. Some developers also may want to use it as a kind of snapshot for detecting schema regression or they just prefer to read the SDL file to explore the API instead of reading the complicated TypeGraphQL-based app code, navigating through the GraphiQL or GraphQL Playground. To accomplish this demand, TypeGraphQL allows you to create a schema definition file in two ways. +TypeGraphQL's main feature is creating the schema using only TypeScript classes and decorators. However, there might be a need for the schema to be printed into a `schema.graphql` file and there are plenty of reasons for that. Mainly, the schema SDL file is needed for GraphQL ecosystem tools that perform client-side queries autocompletion and validation. Some developers also may want to use it as a kind of snapshot for detecting schema regression or they just prefer to read the SDL file to explore the API instead of reading the complicated TypeGraphQL-based app code, navigating through the GraphiQL or GraphQL Playground. To accomplish this demand, TypeGraphQL allows you to create a schema definition file in two ways. -The first one is to generate it automatically on every build of the schema - just pass `emitSchemaFile: true` to the `buildSchema` options in order to emit the `schema.gql` in the root of the project's working directory. You can also manually specify the path and the file name where the schema definition should be written or even specify `PrintSchemaOptions` to configure the look and format of the schema definition. +The first one is to generate it automatically on every build of the schema - just pass `emitSchemaFile: true` to the `buildSchema` options in order to emit the `schema.graphql` in the root of the project's working directory. You can also manually specify the path and the file name where the schema definition should be written or even specify `PrintSchemaOptions` to configure the look and format of the schema definition. -```typescript +```ts const schema = await buildSchema({ resolvers: [ExampleResolver], - // automatically create `schema.gql` file with schema definition in project's working directory + // Automatically create `schema.graphql` file with schema definition in project's working directory emitSchemaFile: true, - // or create the file with schema in selected path - emitSchemaFile: path.resolve(__dirname, "__snapshots__/schema/schema.gql"), - // or pass a config object + // Or create the file with schema in selected path + emitSchemaFile: path.resolve(__dirname, "__snapshots__/schema/schema.graphql"), + // Or pass a config object emitSchemaFile: { - path: __dirname + "/schema.gql", - commentDescriptions: true, - sortedSchema: false, // by default the printed schema is sorted alphabetically + path: __dirname + "/schema.graphql", + sortedSchema: false, // By default the printed schema is sorted alphabetically }, }); ``` The second way to emit the schema definition file is by doing it programmatically. We would use the `emitSchemaDefinitionFile` function (or it's sync version `emitSchemaDefinitionFileSync`) and pass in the path, along with the schema object. We can use this among others as part of a testing script that checks if the snapshot of the schema definition is correct or to automatically generate it on every file change during local development. -```typescript +```ts import { emitSchemaDefinitionFile } from "type-graphql"; + // ... hypotheticalFileWatcher.watch("./src/**/*.{resolver,type,input,arg}.ts", async () => { const schema = getSchemaNotFromBuildSchemaFunction(); - await emitSchemaDefinitionFile("/path/to/folder/schema.gql", schema); + await emitSchemaDefinitionFile("/path/to/folder/schema.graphql", schema); }); ``` @@ -41,24 +41,24 @@ If we want the custom directives to appear in the generated schema definition fi Below there is an example that uses the `printSchemaWithDirectives` function from [`@graphql-tools/utils`](https://www.graphql-tools.com/docs/api/modules/utils): -```typescript +```ts import { GraphQLSchema, lexicographicSortSchema } from "graphql"; import { printSchemaWithDirectives } from "@graphql-tools/utils"; -import { outputFile } from "type-graphql/dist/helpers/filesystem"; +import fs from "node:fs/promises"; export async function emitSchemaDefinitionWithDirectivesFile( schemaFilePath: string, schema: GraphQLSchema, ): Promise { const schemaFileContent = printSchemaWithDirectives(lexicographicSortSchema(schema)); - await outputFile(schemaFilePath, schemaFileContent); + await fs.writeFile(schemaFilePath, schemaFileContent); } ``` The usage of `emitSchemaDefinitionWithDirectivesFile` function is the same as with standard `emitSchemaDefinitionFile`: -```typescript +```ts const schema = await buildSchema(/*...*/); -await emitSchemaDefinitionWithDirectivesFile("/path/to/folder/schema.gql", schema); +await emitSchemaDefinitionWithDirectivesFile("/path/to/folder/schema.graphql", schema); ``` diff --git a/docs/enums.md b/docs/enums.md index 5211b83c1..bcb5e46a4 100644 --- a/docs/enums.md +++ b/docs/enums.md @@ -10,8 +10,8 @@ GraphQL also has enum type support, so TypeGraphQL allows us to use TypeScript e Let's create a TypeScript enum. It can be a numeric or string enum - the internal values of enums are taken from the enum definition values and the public names taken from the enum keys: -```typescript -// implicit value 0, 1, 2, 3 +```ts +// Implicit value 0, 1, 2, 3 enum Direction { UP, DOWN, @@ -19,29 +19,29 @@ enum Direction { RIGHT, } -// or explicit values +// Or explicit values enum Direction { - UP = "up", - DOWN = "down", - LEFT = "left", - RIGHT = "right", + UP = "UP", + DOWN = "DOWN", + LEFT = "LEFT", + RIGHT = "RIGHT", } ``` To tell TypeGraphQL about our enum, we would ideally mark the enums with the `@EnumType()` decorator. However, TypeScript decorators only work with classes, so we need to make TypeGraphQL aware of the enums manually by calling the `registerEnumType` function and providing the enum name for GraphQL: -```typescript +```ts import { registerEnumType } from "type-graphql"; registerEnumType(Direction, { - name: "Direction", // this one is mandatory - description: "The basic directions", // this one is optional + name: "Direction", // Mandatory + description: "The basic directions", // Optional }); ``` In case we need to provide additional GraphQL-related config for values, like description or deprecation reason, we can use `valuesConfig` property and put the data inside it, e.g.: -```typescript +```ts enum Direction { UP = "UP", DOWN = "DOWN", @@ -83,10 +83,10 @@ enum Direction { The last step is very important: TypeScript has limited reflection ability, so this is a case where we have to explicitly provide the enum type for object type fields, input type fields, args, and the return type of queries and mutations: -```typescript +```ts @InputType() class JourneyInput { - @Field(type => Direction) // it's very important + @Field(type => Direction) // Mandatory direction: Direction; } ``` @@ -95,7 +95,7 @@ Without this annotation, the generated GQL type would be `String` or `Float` (de With all that in place, we can use our enum directly in our code πŸ˜‰ -```typescript +```ts @Resolver() class SpriteResolver { private sprite = getMarioSprite(); @@ -116,7 +116,7 @@ class SpriteResolver { this.sprite.position.x++; break; default: - // it will never be hitten ;) + // Never reached return false; } @@ -131,7 +131,7 @@ Enums in TypeGraphQL are designed with server side in mind - the runtime will ma So if we would like to share the types definition and use the enum on the client side app or use the enums directly on the server app e.g. in tests, we have to use the direct mapping of the enum member names with values, e.g.: -```typescript +```ts enum Direction { UP = "UP", DOWN = "DOWN", diff --git a/docs/esm.md b/docs/esm.md new file mode 100644 index 000000000..127a0eac0 --- /dev/null +++ b/docs/esm.md @@ -0,0 +1,46 @@ +--- +title: ECMAScript Modules +--- + +Since `v2.0.0` release, TypeGraphQL is compatible with ECMAScript modules. + +Thanks to this, we can `import` the `type-graphql` package in the ESM projects without any hassle. + +## TypeScript configuration + +It's important to properly configure the project, so that it uses ESM correctly: + +- the `module` option should be set to `NodeNext` +- the `moduleResolution` option should be set to `"NodeNext"` + +All in all, the `tsconfig.json` file should looks like this: + +```json title="tsconfig.json" +{ + "compilerOptions": { + "target": "es2021", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "experimentalDecorators": true, + "emitDecoratorMetadata": true + } +} +``` + +## Package.json configuration + +It is also important to set `type` option to `"module"` in your `package.json` file: + +```json title="package.json" +{ + "type": "module" +} +``` + +## Imports + +Apart from using `import` syntax, your local imports have to use the `.js` suffix, e.g.: + +```ts +import { MyResolver } from "./resolvers/MyResolver.js"; +``` diff --git a/docs/examples.md b/docs/examples.md index 4e96031ad..a501f1d02 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -3,9 +3,11 @@ title: Examples sidebar_label: List of examples --- -On the [GitHub repository](https://github.com/MichalLytek/type-graphql) there are a few simple examples of how to use different TypeGraphQL features and how well they integrate with 3rd party libraries. +On the [GitHub repository](https://github.com/MichalLytek/type-graphql) there are a few simple [`examples`](https://github.com/MichalLytek/type-graphql/tree/master/examples) of how to use different `TypeGraphQL` features and how well they integrate with 3rd party libraries. -All examples have an `examples.gql` file with sample queries/mutations/subscriptions that we can execute. +To run an example, simply go to the subdirectory (e.g. `cd ./simple-usage`), and then start the server (`npx ts-node ./index.ts`). + +Each subdirectory contains a `examples.graphql` file with predefined GraphQL queries/mutations/subscriptions that you can use in Apollo Studio () and play with them by modifying their shape and data. ## Basics @@ -15,7 +17,7 @@ All examples have an `examples.gql` file with sample queries/mutations/subscript - [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/master/examples/enums-and-unions) - [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/master/examples/simple-subscriptions) -- [Subscriptions (using Redis)](https://github.com/MichalLytek/type-graphql/tree/master/examples/redis-subscriptions) +- [Subscriptions (using Redis) \*\*](https://github.com/MichalLytek/type-graphql/tree/master/examples/redis-subscriptions) - [Interfaces](https://github.com/MichalLytek/type-graphql/tree/master/examples/interfaces-inheritance) - [Extensions (metadata)](https://github.com/MichalLytek/type-graphql/tree/master/examples/extensions) @@ -37,11 +39,13 @@ All examples have an `examples.gql` file with sample queries/mutations/subscript - [TypeORM (manual, synchronous) \*](https://github.com/MichalLytek/type-graphql/tree/master/examples/typeorm-basic-usage) - [TypeORM (automatic, lazy relations) \*](https://github.com/MichalLytek/type-graphql/tree/master/examples/typeorm-lazy-relations) -- [MikroORM](https://github.com/MichalLytek/type-graphql/tree/master/examples/mikro-orm) -- [Typegoose](https://github.com/MichalLytek/type-graphql/tree/master/examples/typegoose) -- [Apollo federation](https://github.com/MichalLytek/type-graphql/tree/master/examples/apollo-federation) +- [MikroORM \*](https://github.com/MichalLytek/type-graphql/tree/master/examples/mikro-orm) +- [Typegoose \*](https://github.com/MichalLytek/type-graphql/tree/master/examples/typegoose) +- [Apollo Federation](https://github.com/MichalLytek/type-graphql/tree/master/examples/apollo-federation) +- [Apollo Federation 2](https://github.com/MichalLytek/type-graphql/tree/master/examples/apollo-federation-2) - [Apollo Cache Control](https://github.com/MichalLytek/type-graphql/tree/master/examples/apollo-cache) -- [Apollo Client state](https://github.com/MichalLytek/type-graphql/tree/master/examples/apollo-client) -- [GraphQL Modules](https://github.com/MichalLytek/type-graphql/tree/master/examples/graphql-modules) +- [GraphQL Scalars](https://github.com/MichalLytek/type-graphql/tree/master/examples/graphql-scalars) +- [TSyringe](https://github.com/MichalLytek/type-graphql/tree/master/examples/tsyringe) -_\* Note that we need to edit the TypeORM example's `index.ts` with the credentials of our local database_ +_\* Note that we need to provide the environment variable `DATABASE_URL` with connection parameters to your local database_ \ +_\*\* Note that we need to provide the environment variable `REDIS_URL` with connection parameters to your local Redis instance_ diff --git a/docs/extensions.md b/docs/extensions.md index 739720ec9..00588f569 100644 --- a/docs/extensions.md +++ b/docs/extensions.md @@ -13,26 +13,26 @@ For such use cases, **TypeGraphQL** provides the `@Extensions` decorator, which Adding extensions to the schema type is as simple as using the `@Extensions` decorator and passing it an object of the custom data we want: -```typescript +```ts @Extensions({ complexity: 2 }) ``` We can pass several fields to the decorator: -```typescript +```ts @Extensions({ logMessage: "Restricted access", logLevel: 1 }) ``` And we can also decorate a type several times. The snippet below shows that this attaches the exact same extensions data to the schema type as the snippet above: -```typescript +```ts @Extensions({ logMessage: "Restricted access" }) @Extensions({ logLevel: 1 }) ``` If we decorate the same type several times with the same extensions key, the one defined at the bottom takes precedence: -```typescript +```ts @Extensions({ logMessage: "Restricted access" }) @Extensions({ logMessage: "Another message" }) ``` @@ -50,7 +50,7 @@ TypeGraphQL classes with the following decorators can be annotated with `@Extens So the `@Extensions` decorator can be placed over the class property/method or over the type class itself, and multiple times if necessary, depending on what we want to do with the extensions data: -```typescript +```ts @Extensions({ roles: ["USER"] }) @ObjectType() class Foo { @@ -95,7 +95,7 @@ Once we have decorated the necessary types with extensions, the executable schem Here is a simple example of a global middleware that will be logging a message on field resolver execution whenever the field is decorated appropriately with `@Extensions`: -```typescript +```ts export class LoggerMiddleware implements MiddlewareInterface { constructor(private readonly logger: Logger) {} diff --git a/docs/faq.md b/docs/faq.md index bdc98fbfc..ec05fc69b 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -26,10 +26,6 @@ Otherwise, `graphql-js` will not be able to correctly detect the underlying Grap ## Bootstrapping -### Should I use an array of manually imported resolver classes or a glob path string? - -Using a path to resolver module files compels us to structure our project folders or consistently name files with a prefix/suffix and when there are several resolver classes, this might be easier than having to remember to import and register every new class. - ### How do I fix this error? `Cannot use GraphQLSchema "[object Object]" from another module or realm` This error occurs mostly when there are more than one version of the `graphql-js` module in the project. @@ -88,8 +84,8 @@ data: [DataPoint] In GraphQL, input objects have a separate type in the system because object types can contain fields that express circular references or references to interfaces and unions, neither of which are appropriate for use as input arguments. However, if there are only simple fields in the class definition, reuse the code between the InputType and the ObjectType by decorating the ObjectType class with `@InputType`. Remember to set a new name of the type in the decorator parameter: -```typescript -@ObjectType() // name inferred to `Person` +```ts +@ObjectType() // Name inferred as 'Person' from class name @InputType("PersonInput") export class Person {} ``` diff --git a/docs/generic-types.md b/docs/generic-types.md index beb733698..451a788f7 100644 --- a/docs/generic-types.md +++ b/docs/generic-types.md @@ -2,19 +2,19 @@ title: Generic Types --- -[Type Inheritance](inheritance.md) is a great way to reduce code duplication by extracting common fields to the base class. But in some cases, the strict set of fields is not enough because we might need to declare the types of some fields in a more flexible way, like a type parameter (e.g. `items: T[]` in case of a pagination). +[Type Inheritance](./inheritance.md) is a great way to reduce code duplication by extracting common fields to the base class. But in some cases, the strict set of fields is not enough because we might need to declare the types of some fields in a more flexible way, like a type parameter (e.g. `items: T[]` in case of a pagination). Hence TypeGraphQL also has support for describing generic GraphQL types. ## How to? -Unfortunately, the limited reflection capabilities of TypeScript don't allow for combining decorators with standard generic classes. To achieve behavior like that of generic types, we use the same class-creator pattern like the one described in the [Resolvers Inheritance](inheritance.md) docs. +Unfortunately, the limited reflection capabilities of TypeScript don't allow for combining decorators with standard generic classes. To achieve behavior like that of generic types, we use the same class-creator pattern like the one described in the [Resolvers Inheritance](./inheritance.md) docs. ### Basic usage -Start by defining a `PaginatedResponse` function that creates and returns a `PaginatedResponseClass`: +Start by defining a `PaginatedResponse` function that creates and returns an abstract `PaginatedResponseClass`: -```typescript +```ts export default function PaginatedResponse() { abstract class PaginatedResponseClass { // ... @@ -25,8 +25,8 @@ export default function PaginatedResponse() { To achieve generic-like behavior, the function has to be generic and take some runtime argument related to the type parameter: -```typescript -export default function PaginatedResponse(TItemClass: ClassType) { +```ts +export default function PaginatedResponse(TItemClass: ClassType) { abstract class PaginatedResponseClass { // ... } @@ -34,12 +34,11 @@ export default function PaginatedResponse(TItemClass: ClassType) { } ``` -Then, add proper decorators to the class which might be `@ObjectType`, `@InterfaceType` or `@InputType`. -It also should have set `isAbstract: true` to prevent getting registered in the schema: +Then, add proper decorators to the class which might be `@ObjectType`, `@InterfaceType` or `@InputType`: -```typescript -export default function PaginatedResponse(TItemClass: ClassType) { - @ObjectType({ isAbstract: true }) +```ts +export default function PaginatedResponse(TItemClass: ClassType) { + @ObjectType() abstract class PaginatedResponseClass { // ... } @@ -49,14 +48,13 @@ export default function PaginatedResponse(TItemClass: ClassType) { After that, add fields like in a normal class but using the generic type and parameters: -```typescript -export default function PaginatedResponse(TItemClass: ClassType) { - // `isAbstract` decorator option is mandatory to prevent registering in schema - @ObjectType({ isAbstract: true }) +```ts +export default function PaginatedResponse(TItemClass: ClassType) { + @ObjectType() abstract class PaginatedResponseClass { - // here we use the runtime argument + // Runtime argument @Field(type => [TItemClass]) - // and here the generic type + // Generic type items: TItem[]; @Field(type => Int) @@ -71,10 +69,10 @@ export default function PaginatedResponse(TItemClass: ClassType) { Finally, use the generic function factory to create a dedicated type class: -```typescript +```ts @ObjectType() class PaginatedUserResponse extends PaginatedResponse(User) { - // we can freely add more fields or overwrite the existing one's types + // Add more fields or overwrite the existing one's types @Field(type => [String]) otherInfo: string[]; } @@ -82,12 +80,12 @@ class PaginatedUserResponse extends PaginatedResponse(User) { And then use it in our resolvers: -```typescript +```ts @Resolver() class UserResolver { @Query() users(): PaginatedUserResponse { - // here is your custom business logic, + // Custom business logic, // depending on underlying data source and libraries return { items, @@ -106,16 +104,16 @@ When we need to provide something different than a class (object type) for the f Basically, the parameter that the `PaginatedResponse` function accepts is the value we can provide to `@Field` decorator. So if we want to return an array of strings as the `items` field, we need to add proper types to the function signature, like `GraphQLScalarType` or `String`: -```typescript -export default function PaginatedResponse( +```ts +export default function PaginatedResponse( itemsFieldValue: ClassType | GraphQLScalarType | String | Number | Boolean, ) { - @ObjectType({ isAbstract: true }) + @ObjectType() abstract class PaginatedResponseClass { @Field(type => [itemsFieldValue]) items: TItemsFieldValue[]; - // ...other fields + // ... Other fields } return PaginatedResponseClass; } @@ -123,7 +121,7 @@ export default function PaginatedResponse( And then provide a proper runtime value (like `String`) while creating a proper subtype of generic `PaginatedResponse` object type: -```typescript +```ts @ObjectType() class PaginatedStringsResponse extends PaginatedResponse(String) { // ... @@ -132,17 +130,17 @@ class PaginatedStringsResponse extends PaginatedResponse(String) { ### Types factory -We can also create a generic class without using the `isAbstract` option or the `abstract` keyword. -But types created with this kind of factory will be registered in the schema, so this way is not recommended to extend the types for adding fields. +We can also create a generic class without using the `abstract` keyword. +But with this approach, types created with this kind of factory will be registered in the schema, so this way is not recommended to extend the types for adding fields. To avoid generating schema errors of duplicated `PaginatedResponseClass` type names, we must provide our own unique, generated type name: -```typescript -export default function PaginatedResponse(TItemClass: ClassType) { - // instead of `isAbstract`, we have to provide a unique type name used in schema +```ts +export default function PaginatedResponse(TItemClass: ClassType) { + // Provide a unique type name used in schema @ObjectType(`Paginated${TItemClass.name}Response`) class PaginatedResponseClass { - // the same fields as in the earlier code snippet + // ... } return PaginatedResponseClass; } @@ -150,16 +148,16 @@ export default function PaginatedResponse(TItemClass: ClassType) { Then, we can store the generated class in a variable and in order to use it both as a runtime object and as a type, we must also create a type for this new class: -```typescript +```ts const PaginatedUserResponse = PaginatedResponse(User); type PaginatedUserResponse = InstanceType; @Resolver() class UserResolver { - // remember to provide a runtime type argument to the decorator + // Provide a runtime type argument to the decorator @Query(returns => PaginatedUserResponse) users(): PaginatedUserResponse { - // the same implementation as in the earlier code snippet + // Same implementation as in the earlier code snippet } } ``` diff --git a/docs/getting-started.md b/docs/getting-started.md index 0a1f7166f..f613553cb 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -2,7 +2,7 @@ title: Getting started --- -> Make sure you've completed all the steps described in the [installation instructions](installation.md). +> Make sure you've completed all the steps described in the [installation instructions](./installation.md). To explore all of the powerful capabilities of TypeGraphQL, we will create a sample GraphQL API for cooking recipes. @@ -24,7 +24,7 @@ type Recipe { So we create the `Recipe` class with all its properties and types: -```typescript +```ts class Recipe { id: string; title: string; @@ -36,7 +36,7 @@ class Recipe { Then we decorate the class and its properties with decorators: -```typescript +```ts @ObjectType() class Recipe { @Field(type => ID) @@ -56,13 +56,13 @@ class Recipe { } ``` -The detailed rules of when to use `nullable`, `array` and others are described in the [fields and types docs](types-and-fields.md). +The detailed rules of when to use `nullable`, `array` and others are described in the [fields and types docs](./types-and-fields.md). ## Resolvers After that we want to create typical crud queries and mutations. To do so, we create the resolver (controller) class that will have injected the `RecipeService` in the constructor: -```typescript +```ts @Resolver(Recipe) class RecipeResolver { constructor(private recipeService: RecipeService) {} @@ -104,13 +104,13 @@ class RecipeResolver { ``` We use the `@Authorized()` decorator to restrict access to authorized users only or the users that fulfil the roles requirements. -The detailed rules for when and why we declare `returns => Recipe` functions and others are described in [resolvers docs](resolvers.md). +The detailed rules for when and why we declare `returns => Recipe` functions and others are described in [resolvers docs](./resolvers.md). ## Inputs and Arguments -Ok, but what are `NewRecipeInput` and `RecipesArgs`? They are of course classes: +Ok, but what are `NewRecipeInput` and `RecipesArgs`? They are, of course, classes: -```typescript +```ts @InputType() class NewRecipeInput { @Field() @@ -145,12 +145,12 @@ class RecipesArgs { The last step that needs to be done is to actually build the schema from the TypeGraphQL definition. We use the `buildSchema` function for this: -```typescript +```ts const schema = await buildSchema({ resolvers: [RecipeResolver], }); -// ...creating express server or sth +// ... Server ``` Et voilΓ ! Now we have fully functional GraphQL schema! @@ -185,4 +185,4 @@ That was only the tip of the iceberg - a very simple example with basic GraphQL A lot of these topics are covered in [Ben Awad](https://github.com/benawad)'s [TypeGraphQL video series](https://www.youtube.com/playlist?list=PLN3n1USn4xlma1bBu3Tloe4NyYn9Ko8Gs) on YouTube. -For more complicated cases, go to the [Examples section](examples.md) where you can discover e.g. how well TypeGraphQL integrates with TypeORM. +For more complicated cases, go to the [Examples section](./examples.md) where you can discover e.g. how well TypeGraphQL integrates with TypeORM. diff --git a/docs/inheritance.md b/docs/inheritance.md index 8d5d6eb32..cc2347228 100644 --- a/docs/inheritance.md +++ b/docs/inheritance.md @@ -12,7 +12,7 @@ One of the most known principles of software development is DRY - Don't Repeat Y While creating a GraphQL API, it's a common pattern to have pagination args in resolvers, like `skip` and `take`. So instead of repeating ourselves, we declare it once: -```typescript +```ts @ArgsType() class PaginationArgs { @Field(type => Int) @@ -25,7 +25,7 @@ class PaginationArgs { and then reuse it everywhere: -```typescript +```ts @ArgsType() class GetTodosArgs extends PaginationArgs { @Field() @@ -35,7 +35,7 @@ class GetTodosArgs extends PaginationArgs { This technique also works with input type classes, as well as with object type classes: -```typescript +```ts @ObjectType() class Person { @Field() @@ -57,7 +57,7 @@ A special kind of inheritance in TypeGraphQL is resolver class inheritance. This Since we need to generate unique query/mutation names, we have to create a factory function for our base class: -```typescript +```ts function createBaseResolver() { abstract class BaseResolver {} @@ -69,7 +69,7 @@ Be aware that with some `tsconfig.json` settings (like `declarations: true`) we This factory should take a parameter that we can use to generate the query/mutation names, as well as the type that we would return from the resolvers: -```typescript +```ts function createBaseResolver(suffix: string, objectTypeCls: T) { abstract class BaseResolver {} @@ -77,11 +77,11 @@ function createBaseResolver(suffix: string, objectTypeCls: } ``` -It's very important to mark the `BaseResolver` class using the `@Resolver` decorator with the `{ isAbstract: true }` option that will prevent throwing an error due to registering multiple queries/mutations with the same name. +It's very important to mark the `BaseResolver` class using the `@Resolver` decorator: -```typescript +```ts function createBaseResolver(suffix: string, objectTypeCls: T) { - @Resolver({ isAbstract: true }) + @Resolver() abstract class BaseResolver {} return BaseResolver; @@ -90,9 +90,9 @@ function createBaseResolver(suffix: string, objectTypeCls: We can then implement the resolver methods as usual. The only difference is that we can use the `name` decorator option for `@Query`, `@Mutation` and `@Subscription` decorators to overwrite the name that will be emitted in schema: -```typescript +```ts function createBaseResolver(suffix: string, objectTypeCls: T) { - @Resolver({ isAbstract: true }) + @Resolver() abstract class BaseResolver { protected items: T[] = []; @@ -108,7 +108,7 @@ function createBaseResolver(suffix: string, objectTypeCls: Now we can create a specific resolver class that will extend the base resolver class: -```typescript +```ts const PersonBaseResolver = createBaseResolver("person", Person); @Resolver(of => Person) @@ -119,7 +119,7 @@ export class PersonResolver extends PersonBaseResolver { We can also add specific queries and mutations in our resolver class, as always: -```typescript +```ts const PersonBaseResolver = createBaseResolver("person", Person); @Resolver(of => Person) diff --git a/docs/installation.md b/docs/installation.md index e2ccb1ba2..43e1238de 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -10,22 +10,26 @@ Before getting started with TypeGraphQL we need to install some additional depen ## Packages installation -First, we have to install the main package, as well as [`graphql-js`](https://github.com/graphql/graphql-js) and [`class-validator`](https://github.com/typestack/class-validator) which are peer dependencies of TypeGraphQL: +First, we have to install the main package, as well as [`graphql-js`](https://github.com/graphql/graphql-js) and [`graphql-scalars`](https://github.com/urigo/graphql-scalars) which are peer dependencies of TypeGraphQL: ```sh -npm i graphql class-validator type-graphql +npm install graphql graphql-scalars type-graphql ``` -Also, the `reflect-metadata` shim is required to make the type reflection work: +Also, the `Reflect.metadata()` shim is required to make the type reflection work: ```sh -npm i reflect-metadata +npm install reflect-metadata +# or +npm install core-js ``` We must ensure that it is imported at the top of our entry file (before we use/import `type-graphql` or our resolvers): -```typescript +```ts import "reflect-metadata"; +// or +import "core-js/features/reflect"; ``` ## TypeScript configuration @@ -39,19 +43,11 @@ It's important to set these options in the `tsconfig.json` file of our project: } ``` -`TypeGraphQL` is designed to work with Node.js LTS (10.3+, 12+) and the latest stable releases. It uses features from ES2018 so we should set our `tsconfig.json` file appropriately: +`TypeGraphQL` is designed to work with Node.js LTS and the latest stable releases. It uses features from ES2021 so we should set our `tsconfig.json` file appropriately: ```js { - "target": "es2018" // or newer if your node.js version supports this -} -``` - -Due to using the `graphql-subscription` dependency that relies on an `AsyncIterator`, we may also have to provide the `esnext.asynciterable` to the `lib` option: - -```json -{ - "lib": ["es2018", "esnext.asynciterable"] + "target": "es2021" // Or newer if Node.js version supports it } ``` @@ -60,9 +56,8 @@ All in all, the minimal `tsconfig.json` file example looks like this: ```json { "compilerOptions": { - "target": "es2018", + "target": "es2021", "module": "commonjs", - "lib": ["es2018", "esnext.asynciterable"], "experimentalDecorators": true, "emitDecoratorMetadata": true } diff --git a/docs/interfaces.md b/docs/interfaces.md index 45ccdef7d..eab747f96 100644 --- a/docs/interfaces.md +++ b/docs/interfaces.md @@ -12,13 +12,13 @@ Read more about the GraphQL Interface Type in the [official GraphQL docs](https: TypeScript has first class support for interfaces. Unfortunately, they only exist at compile-time, so we can't use them to build GraphQL schema at runtime by using decorators. -Luckily, we can use an abstract class for this purpose. It behaves almost like an interface as it can't be "newed" but it can be implemented by another class. The only difference is that it just won't prevent developers from implementing a method or initializing a field. So, as long as we treat the abstract class like an interface, we can safely use it. +Luckily, we can use an abstract class for this purpose. It behaves almost like an interface as it can't be instantiated but it can be implemented by another class. The only difference is that it just won't prevent developers from implementing a method or initializing a field. So, as long as we treat the abstract class like an interface, we can safely use it. ## Defining interface type How do we create a GraphQL interface definition? We create an abstract class and decorate it with the `@InterfaceType()` decorator. The rest is exactly the same as with object types: we use the `@Field` decorator to declare the shape of the type: -```typescript +```ts @InterfaceType() abstract class IPerson { @Field(type => ID) @@ -34,7 +34,7 @@ abstract class IPerson { We can then use this interface type class like an interface in the object type class definition: -```typescript +```ts @ObjectType({ implements: IPerson }) class Person implements IPerson { id: string; @@ -49,7 +49,7 @@ It is also allowed to omit the decorators since the GraphQL types will be copied We can also extend the base interface type abstract class as well because all the fields are inherited and emitted in schema: -```typescript +```ts @ObjectType({ implements: IPerson }) class Person extends IPerson { @Field() @@ -63,7 +63,7 @@ Since `graphql-js` version `15.0`, it's also possible for interface type to [imp To accomplish this, we can just use the same syntax that we utilize for object types - the `implements` decorator option: -```typescript +```ts @InterfaceType() class Node { @Field(type => ID) @@ -80,10 +80,10 @@ class Person extends Node { } ``` -Also, when we implement the interface that already implements other interface, we need to put them all in `implements` array in `@ObjectType` decorator option, e.g.: +Also, when we implement the interface that already implements other interface, there's no need to put them all in `implements` array in `@ObjectType` decorator option - only the closest one in the inheritance chain is required, e.g.: -```typescript -@ObjectType({ implements: [Person, Node] }) +```ts +@ObjectType({ implements: [Person] }) class Student extends Person { @Field() universityName: string; @@ -115,7 +115,7 @@ type Student implements Node & Person { What's more, we can define resolvers for the interface fields, using the same syntax we would use when defining one for our object type: -```typescript +```ts @InterfaceType() abstract class IPerson { @Field() @@ -143,7 +143,7 @@ interface IPerson { We can just use `@Arg` or `@Args` decorators as usual: -```typescript +```ts @InterfaceType() abstract class IPerson { @Field() @@ -156,7 +156,7 @@ abstract class IPerson { Unfortunately, TypeScript doesn't allow using decorators on abstract methods. So if we don't want to provide implementation for that field resolver, only to enforce some signature (args and return type), we have to throw an error inside the body: -```typescript +```ts @InterfaceType() abstract class IPerson { @Field() @@ -168,7 +168,7 @@ abstract class IPerson { And then we need to extend the interface class and override the method by providing its body - it is required for all object types that implements that interface type: -```typescript +```ts @ObjectType({ implements: IPerson }) class Person extends IPerson { avatar(size: number): string { @@ -179,7 +179,7 @@ class Person extends IPerson { In order to extend the signature by providing additional arguments (like `format`), we need to redeclare the whole field signature: -```typescript +```ts @ObjectType({ implements: IPerson }) class Person implements IPerson { @Field() @@ -191,7 +191,7 @@ class Person implements IPerson { Resolvers for interface type fields can be also defined on resolvers classes level, by using the `@FieldResolver` decorator: -```typescript +```ts @Resolver(of => IPerson) class IPersonResolver { @FieldResolver() @@ -222,7 +222,7 @@ Then we need to add all the object types (that implement this interface type and ```ts const schema = await buildSchema({ resolvers, - // here we provide such object types + // Provide orphaned object types orphanedTypes: [Person, Animal, Recipe], }); ``` @@ -235,13 +235,13 @@ Be aware that when our object type is implementing a GraphQL interface type, **w We can also provide our own `resolveType` function implementation to the `@InterfaceType` options. This way we can return plain objects in resolvers and then determine the returned object type by checking the shape of the data object, the same ways [like in unions](./unions.md), e.g.: -```typescript +```ts @InterfaceType({ resolveType: value => { if ("grades" in value) { - return "Student"; // schema name of the type as a string + return "Student"; // Schema name of type string } - return Person; // or the object type class + return Person; // Or object type class }, }) abstract class IPerson { diff --git a/docs/introduction.md b/docs/introduction.md index 89704bcfd..f485a52bd 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -10,7 +10,7 @@ We all love GraphQL! It's really great and solves many problems that we have wit **TypeGraphQL** is a library that makes this process enjoyable by defining the schema using only classes and a bit of decorator magic. Example object type: -```typescript +```ts @ObjectType() class Recipe { @Field() @@ -33,13 +33,13 @@ Why? Let's take a look at the steps we usually have to take. First, we create all the schema types in SDL. We also create our data models using [ORM classes](https://github.com/typeorm/typeorm), which represent our database entities. Then we start to write resolvers for our queries, mutations and fields. This forces us, however, to begin with creating TypeScript interfaces for all arguments and inputs and/or object types. After that, we can actually implement the resolvers, using weird generic signatures, e.g.: -```typescript +```ts export const getRecipesResolver: GraphQLFieldResolver = async ( _, args, ctx, ) => { - // common tasks repeatable for almost every resolver + // Common tasks repeatable for almost every resolver const auth = Container.get(AuthService); if (!auth.check(ctx.user)) { throw new NotAuthorizedError(); @@ -47,7 +47,7 @@ export const getRecipesResolver: GraphQLFieldResolver { const start = Date.now(); await next(); @@ -30,7 +30,7 @@ export const ResolveTime: MiddlewareFn = async ({ info }, next) => { Middleware also has the ability to intercept the result of a resolver's execution. It's not only able to e.g. create a log but also replace the result with a new value: -```typescript +```ts export const CompetitorInterceptor: MiddlewareFn = async (_, next) => { const result = await next(); if (result === "typegql") { @@ -46,7 +46,7 @@ It might not seem very useful from the perspective of this library's users but t If we only want to do something before an action, like log the access to the resolver, we can just place the `return next()` statement at the end of our middleware: -```typescript +```ts const LogAccess: MiddlewareFn = ({ context, info }, next) => { const username: string = context.username || "guest"; console.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`); @@ -62,7 +62,7 @@ We can also throw an error in the middleware if the execution must be terminated This way we can create a guard that blocks access to the resolver and prevents execution or any data return. -```typescript +```ts export const CompetitorDetector: MiddlewareFn = async ({ args }, next) => { if (args.frameworkName === "type-graphql") { return "TypeGraphQL"; @@ -76,13 +76,13 @@ export const CompetitorDetector: MiddlewareFn = async ({ args }, next) => { ### Reusable Middleware -Sometimes middleware has to be configurable, just like we pass a `roles` array to the [`@Authorized()` decorator](authorization.md). In this case, we should create a simple middleware factory - a function that takes our configuration as a parameter and returns a middleware that uses the provided value. +Sometimes middleware has to be configurable, just like we pass a `roles` array to the [`@Authorized()` decorator](./authorization.md). In this case, we should create a simple middleware factory - a function that takes our configuration as a parameter and returns a middleware that uses the provided value. -```typescript +```ts export function NumberInterceptor(minValue: number): MiddlewareFn { return async (_, next) => { const result = await next(); - // hide values below minValue + // Hide values below minValue if (typeof result === "number" && result < minValue) { return null; } @@ -97,20 +97,20 @@ Remember to call this middleware with an argument, e.g. `NumberInterceptor(3.0)` Middleware can also catch errors that were thrown during execution. This way, they can easily be logged and even filtered for info that can't be returned to the user: -```typescript +```ts export const ErrorInterceptor: MiddlewareFn = async ({ context, info }, next) => { try { return await next(); } catch (err) { - // write error to file log + // Write error to file log fileLog.write(err, context, info); - // hide errors from db like printing sql query + // Hide errors from db like printing sql query if (someCondition(err)) { throw new Error("Unknown error occurred!"); } - // rethrow the error + // Rethrow the error throw err; } }; @@ -118,11 +118,11 @@ export const ErrorInterceptor: MiddlewareFn = async ({ context, info }, nex ### Class-based Middleware -Sometimes our middleware logic can be a bit complicated - it may communicate with a database, write logs to file, etc., so we might want to test it. In that case we create class middleware that is able to benefit from [dependency injection](dependency-injection.md) and easily mock a file logger or a database repository. +Sometimes our middleware logic can be a bit complicated - it may communicate with a database, write logs to file, etc., so we might want to test it. In that case we create class middleware that is able to benefit from [dependency injection](./dependency-injection.md) and easily mock a file logger or a database repository. To accomplish this, we implement a `MiddlewareInterface`. Our class must have the `use` method that conforms with the `MiddlewareFn` signature. Below we can see how the previously defined `LogAccess` middleware looks after the transformation: -```typescript +```ts export class LogAccess implements MiddlewareInterface { constructor(private readonly logger: Logger) {} @@ -140,7 +140,7 @@ export class LogAccess implements MiddlewareInterface { To attach middleware to a resolver, place the `@UseMiddleware()` decorator above the field or resolver declaration. It accepts an array of middleware that will be called in the provided order. We can also pass them without an array as it supports [rest parameters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters): -```typescript +```ts @Resolver() export class RecipeResolver { @Query() @@ -151,9 +151,9 @@ export class RecipeResolver { } ``` -We can also attach the middleware to the `ObjectType` fields, the same way as with the [`@Authorized()` decorator](authorization.md). +We can also attach the middleware to the `ObjectType` fields, the same way as with the [`@Authorized()` decorator](./authorization.md). -```typescript +```ts @ObjectType() export class Recipe { @Field() @@ -171,7 +171,7 @@ However, for common middleware like measuring resolve time or catching errors, i Hence, in TypeGraphQL we can also register a global middleware that will be called for each query, mutation, subscription and field resolver. For this, we use the `globalMiddlewares` property of the `buildSchema` configuration object: -```typescript +```ts const schema = await buildSchema({ resolvers: [RecipeResolver], globalMiddlewares: [ErrorInterceptor, ResolveTime], @@ -180,7 +180,7 @@ const schema = await buildSchema({ ### Custom Decorators -If we want to use middlewares with a more descriptive and declarative API, we can also create a custom method decorators. See how to do this in [custom decorators docs](custom-decorators.md#method-decorators). +If we want to use middlewares with a more descriptive and declarative API, we can also create a custom method decorators. See how to do this in [custom decorators docs](./custom-decorators.md#method-decorators). ## Example diff --git a/docs/migration-guide.md b/docs/migration-guide.md new file mode 100644 index 000000000..31960e11e --- /dev/null +++ b/docs/migration-guide.md @@ -0,0 +1,100 @@ +--- +title: Migration Guide +sidebar_label: v1.x -> v2.0 +--- + +> This chapter contains migration guide, that will help you upgrade your codebase from using old Typegraphql `v1.x` into the newest `v2.0` release. +> +> If you just started using TypeGraphQL and you have `v2.0` installed, you can skip this chapter and go straight into the "Advanced guides" section. + +## New `DateTimeISO` scalar name in schema + +One of the breaking change released in `v2.0` is using `Date` scalars from `graphql-scalars` package, instead of custom ones that were built-in in TypegraphQL. + +This means that the exported `GraphQLISODateTime` scalar is registered in schema under a changed name - `DateTimeISO`. If you don't plan to use other `DateTime` scalar in your project and you need to restore the existing scalar name for an easy upgrade to the latest TypeGraphQL version (without rewriting your GraphQL queries), here's a simple snippet for you to use. + +First, you need to create an alias for the `GraphQLDateTimeISO` scalar: + +```ts +import { GraphQLDateTimeISO } from "graphql-scalars"; +import { GraphQLScalarType } from "graphql"; + +const AliasedGraphQLDateTimeISO = new GraphQLScalarType({ + ...GraphQLDateTimeISO.toConfig(), + name: "DateTime", // use old name +}); +``` + +And then register the scalars mapping in the schema you build, in order to overwrite the default date scalar: + +```ts +import { buildSchema } from "type-graphql"; + +const schema = await buildSchema({ + resolvers, + scalarsMap: [{ type: Date, scalar: AliasedGraphQLDateTimeISO }], +}); +``` + +An alternative solution would be to just search for `DateTime` via CTRL+F in your codebase and replace with `DateTimeISO` in your queries, if you don't need the backward compatibility for existing released client apps. + +## Subscriptions + +The new `v2.0` release contains a bunch of breaking changes related to the GraphQL subscriptions feature. + +In previous releases, this feature was build upon the [`graphql-subscriptions`](https://github.com/apollographql/graphql-subscriptions) package and it's `PubSub` system. +However, it's become unmaintained in the last years and some alternatives has been developed in the meantime. + +So since `v2.0`, TypeGraphQL relies on the new [`@graphql-yoga/subscriptions`](https://the-guild.dev/graphql/yoga-server/docs/features/subscriptions) package which is built on top of latest ECMAScript features. It also has own `PubSub` implementation which works in a similar fashion, but has a slightly different API. + +We did out best to hide under the hood all the differences between the APIs of those packages, but some breaking changes had to occurred in the TypeGraphQL API. + +### The `pubSub` option of `buildSchema` + +It is now required to pass the `PubSub` instance as the config option of `buildSchema` function. +Previously, you could omit it and rely on the default one created by TypeGraphQL. + +The reason for this change is that `@graphql-yoga/subscriptions` package allows to create a type-safe `PubSub` instance via the [generic `createPubSub` function](https://the-guild.dev/graphql/yoga-server/v2/features/subscriptions#topics), so you can add type info about the topics and params required while using `.publish()` method. + +Simple example of the new API: + +```ts +import { buildSchema } from "type-graphql"; +import { createPubSub } from "@graphql-yoga/subscriptions"; + +export const pubSub = createPubSub<{ + NOTIFICATIONS: [NotificationPayload]; + DYNAMIC_ID_TOPIC: [number, NotificationPayload]; +}>(); + +const schema = await buildSchema({ + resolver, + pubSub, +}); +``` + +Be aware that you can use any `PubSub` system you want, not only the `graphql-yoga` one. +The only requirement is to comply with the exported `PubSub` interface - having proper `.subscribe()` and `.publish()` methods. + +### No `@PubSub` decorator + +The consequence of not having automatically created, default `PubSub` instance, is that you don't need access to the internally-created `PubSub` instance. + +Hence, the `@PubSub` decorator was removed - please use dependency injection system if you don't want to have a hardcoded import. The corresponding `Publisher` type was also removed as it was not needed anymore. + +### Renamed and removed types + +There was some inconsistency in naming of the decorator option functions argument types, which was unified in the `v2.0` release. + +If you reference those types in your code (`filter` or `subscribe` decorator option functions), make sure you update your type annotation and imports to the new name. + +- `ResolverFilterData` -> `SubscriptionHandlerData` +- `ResolverTopicData` -> `SubscribeResolverData` + +Also, apart from the `Publisher` type mentioned above, the `PubSubEngine` type has been removed and is no longer exported from the package. + +### Topic with Dynamic ID + +As TypeGraphQL uses `@graphql-yoga/subscriptions` under the hood, it also aims to use its features. And one of the extension to the old `PubSub` system used in `v1.x` is ability to not only use dynamic topics but a topic with a dynamic id. + +You can read more about this new feature in [subscription docs](./subscriptions.md#topic-with-dynamic-id). diff --git a/docs/nestjs.md b/docs/nestjs.md index 978c94039..e0cd0b328 100644 --- a/docs/nestjs.md +++ b/docs/nestjs.md @@ -12,7 +12,7 @@ It allows to use TypeGraphQL features while integrating with NestJS modules syst The usage is similar to the official `@nestjs/graphql` package. First you need to register your resolver classes in `providers` of the `@Module` : -```typescript +```ts @Module({ providers: [RecipeResolver, RecipeService], }) @@ -21,13 +21,12 @@ export default class RecipeModule {} Then you need to register the TypeGraphQL module in your root module - you can pass there all standard `buildSchema` options: -```typescript +```ts @Module({ imports: [ TypeGraphQLModule.forRoot({ emitSchemaFile: true, authChecker, - dateScalarMode: "timestamp", context: ({ req }) => ({ currentUser: req.user }), }), RecipeModule, @@ -45,4 +44,4 @@ To achieve the same goals, you can use standard TypeGraphQL equivalents - middle ## Documentation and examples -You can find some examples and more detailed info about the installation and the usage [in the separate GitHub repository](https://github.com/MichalLytek/typegraphql-nestjs/). +You can find some examples and more detailed info about the installation and the usage [in the separate GitHub repository](https://github.com/MichalLytek/typegraphql-nestjs). diff --git a/docs/performance.md b/docs/performance.md index ece807b53..1acd462c9 100644 --- a/docs/performance.md +++ b/docs/performance.md @@ -8,7 +8,7 @@ While this enable easy and convenient development, it's sometimes a tradeoff in ## Benchmarks -To measure the overhead of the abstraction, a few demo examples were made to compare the usage of TypeGraphQL against the implementations using "bare metal" - raw `graphql-js` library. The benchmarks are located in a [folder on the GitHub repo](https://github.com/MichalLytek/type-graphql/tree/master/benchmarks). +To measure the overhead of the abstraction, a few demo examples were made to compare the usage of TypeGraphQL against the implementations using "bare metal" - raw `graphql-js` library. The benchmarks are located in a [folder on the GitHub repo](../benchmarks). The most demanding cases like returning an array of 25 000 nested objects showed that in some cases it might be about 5 times slower. @@ -38,7 +38,7 @@ The whole middleware stack will be soon redesigned with a performance in mind an When we have a query that returns a huge amount of JSON-like data and we don't need any field-level access control or other custom middlewares, we can turn off the whole authorization and middlewares stack for selected field resolver using a `{ simple: true }` decorator option, e.g.: -```typescript +```ts @ObjectType() class SampleObject { @Field() @@ -51,7 +51,7 @@ class SampleObject { Moreover, we can also apply this behavior for all the fields of the object type by using a `{ simpleResolvers: true }` decorator option, e.g.: -```typescript +```ts @ObjectType({ simpleResolvers: true }) class Post { @Field() @@ -65,14 +65,14 @@ class Post { } ``` -This simple trick can speed up the execution up to 76%! The benchmarks show that using simple resolvers allows for as fast execution as with bare `graphql-js` - the measured overhead is only about ~13%, which is a much more reasonable value than 500%. Below you can see [the benchmarks results](https://github.com/MichalLytek/type-graphql/tree/master/benchmarks): +This simple trick can speed up the execution up to 76%! The benchmarks show that using simple resolvers allows for as fast execution as with bare `graphql-js` - the measured overhead is only about ~13%, which is a much more reasonable value than 500%. Below you can see [the benchmarks results](../benchmarks): -| | 25 000 array items | -| ----------------------------------------------------------------------------- | :----------------: | -| `graphql-js` | 265.52 ms | -| Standard TypeGraphQL | 310.36 ms | -| TypeGraphQL with a global middleware | 1253.28 ms | -| **TypeGraphQL with "simpleResolvers" applied
(and a global middleware)** | **299.61 ms** | +| | 25 000 array items | +| ------------------------------------------------------------------------ | :----------------: | +| `graphql-js` | 265.52 ms | +| Standard TypeGraphQL | 310.36 ms | +| TypeGraphQL with a global middleware | 1253.28 ms | +| **TypeGraphQL with "simpleResolvers" applied (and a global middleware)** | **299.61 ms** | > This optimization **is not turned on by default** mostly because of the global middlewares and authorization feature. diff --git a/docs/prisma.md b/docs/prisma.md index 1884af476..c7807dad9 100644 --- a/docs/prisma.md +++ b/docs/prisma.md @@ -1,35 +1,34 @@ --- -title: Prisma 2 Integration -sidebar_label: Prisma 2 +title: Prisma Integration +sidebar_label: Prisma --- -TypeGraphQL provides an integration with Prisma 2 by the [`typegraphql-prisma` package](https://www.npmjs.com/package/typegraphql-prisma). +TypeGraphQL provides an integration with Prisma by the [`typegraphql-prisma` package](https://www.npmjs.com/package/typegraphql-prisma). -It generates the type classes and CRUD resolvers based on the Prisma schema, so you can execute complex queries or mutations that corresponds to the Prisma actions, without having to write any code for that. +It generates the type classes and CRUD resolvers based on the Prisma schema, so we can execute complex queries or mutations that corresponds to the Prisma actions, without having to write any code for that. ## Overview -To make use of the prisma integration, first you need to add a new generator to the `schema.prisma` file: +To make use of the prisma integration, first we need to add a new generator to the `schema.prisma` file: ```sh generator typegraphql { provider = "typegraphql-prisma" - output = "../src/generated/typegraphql-prisma" } ``` -Then, after running `prisma generate` you can import the generated classes and use them to build your schema: +Then, after running `prisma generate` we can import the generated resolvers classes and use them to build our schema: -```typescript -import { User, UserRelationsResolver, UserCrudResolver } from "./generated/typegraphql-prisma"; +```ts +import { resolvers } from "@generated/type-graphql"; const schema = await buildSchema({ - resolvers: [CustomUserResolver, UserRelationsResolver, UserCrudResolver], + resolvers, validate: false, }); ``` -So you will be able to execute such complex query that talks with the db in just a few minutes! +So we will be able to execute a complex query, that talks with the real database, in just a few minutes! ```graphql query GetSomeUsers { @@ -48,6 +47,6 @@ query GetSomeUsers { ## Documentation and examples -To read about all the `typegraphql-prisma` features, like exposing selected Prisma actions or changing exposed model type name, as well as how to write a custom query or how to add some fields to model type, please check the docs [on the separate GitHub repository](https://github.com/MichalLytek/typegraphql-prisma/blob/main/Readme.md). +To read about all the `typegraphql-prisma` features, like exposing selected Prisma actions or changing exposed model type name, as well as how to write a custom query or how to add some fields to model type, please check the docs [on the dedicated website](https://prisma.typegraphql.com). -You can find there also some examples and more detailed info about the installation and the configuration. +There also can be found the links to some examples and more detailed info about the installation and the configuration. diff --git a/docs/resolvers.md b/docs/resolvers.md index 8010ced9e..e09248e67 100644 --- a/docs/resolvers.md +++ b/docs/resolvers.md @@ -2,7 +2,7 @@ title: Resolvers --- -Besides [declaring GraphQL's object types](types-and-fields.md), TypeGraphQL allows us to easily create queries, mutations and field resolvers - like normal class methods, similar to REST controllers in frameworks like Java `Spring`, .NET `Web API` or TypeScript [`routing-controllers`](https://github.com/typestack/routing-controllers). +Besides [declaring GraphQL's object types](./types-and-fields.md), TypeGraphQL allows us to easily create queries, mutations and field resolvers - like normal class methods, similar to REST controllers in frameworks like Java `Spring`, .NET `Web API` or TypeScript [`routing-controllers`](https://github.com/typestack/routing-controllers). ## Queries and Mutations @@ -10,14 +10,14 @@ Besides [declaring GraphQL's object types](types-and-fields.md), TypeGraphQL all First we create the resolver class and annotate it with the `@Resolver()` decorator. This class will behave like a controller from classic REST frameworks: -```typescript +```ts @Resolver() class RecipeResolver {} ``` -We can use a DI framework (as described in the [dependency injection docs](dependency-injection.md)) to inject class dependencies (like services or repositories) or to store data inside the resolver class - it's guaranteed to be a single instance per app. +We can use a DI framework (as described in the [dependency injection docs](./dependency-injection.md)) to inject class dependencies (like services or repositories) or to store data inside the resolver class - it's guaranteed to be a single instance per app. -```typescript +```ts @Resolver() class RecipeResolver { private recipesCollection: Recipe[] = []; @@ -26,13 +26,13 @@ class RecipeResolver { Then we can create class methods which will handle queries and mutations. For example, let's add the `recipes` query to return a collection of all recipes: -```typescript +```ts @Resolver() class RecipeResolver { private recipesCollection: Recipe[] = []; async recipes() { - // fake async in this example + // Fake async return await this.recipesCollection; } } @@ -42,7 +42,7 @@ We also need to do two things. The first is to add the `@Query` decorator, which marks the class method as a GraphQL query. The second is to provide the return type. Since the method is async, the reflection metadata system shows the return type as a `Promise`, so we have to add the decorator's parameter as `returns => [Recipe]` to declare it resolves to an array of `Recipe` object types. -```typescript +```ts @Resolver() class RecipeResolver { private recipesCollection: Recipe[] = []; @@ -60,7 +60,7 @@ Usually, queries have some arguments - it might be the id of a resource, a searc First is the inline method using the `@Arg()` decorator. The drawback is the need to repeating the argument name (due to a limitation of the reflection system) in the decorator parameter. As we can see below, we can also pass a `defaultValue` option that will be reflected in the GraphQL schema. -```typescript +```ts @Resolver() class RecipeResolver { // ... @@ -76,7 +76,7 @@ class RecipeResolver { This works well when there are 2 - 3 args. But when you have many more, the resolver's method definitions become bloated. In this case we can use a class definition to describe the arguments. It looks like the object type class but it has the `@ArgsType()` decorator on top. -```typescript +```ts @ArgsType() class GetRecipesArgs { @Field(type => Int, { nullable: true }) @@ -95,11 +95,11 @@ We can define default values for optional fields in the `@Field()` decorator usi > Be aware that `defaultValue` works only for input args and fields, like `@Arg`, `@ArgsType` and `@InputType`. > Setting `defaultValue` does not affect `@ObjectType` or `@InterfaceType` fields as they are for output purposes only. -Also, this way of declaring arguments allows you to perform validation. You can find more details about this feature in the [validation docs](validation.md). +Also, this way of declaring arguments allows you to perform validation. You can find more details about this feature in the [validation docs](./validation.md). We can also define helper fields and methods for our args or input classes. But be aware that **defining constructors is strictly forbidden** and we shouldn't use them there, as TypeGraphQL creates instances of args and input classes under the hood by itself. -```typescript +```ts import { Min, Max } from "class-validator"; @ArgsType() @@ -116,7 +116,7 @@ class GetRecipesArgs { @Field({ nullable: true }) title?: string; - // helpers - index calculations + // Helpers - index calculations get startIndex(): number { return this.skip; } @@ -129,13 +129,13 @@ class GetRecipesArgs { Then all that is left to do is use the args class as the type of the method parameter. We can use the destructuring syntax to gain access to single arguments as variables, instead of the reference to the whole args object. -```typescript +```ts @Resolver() class RecipeResolver { // ... @Query(returns => [Recipe]) async recipes(@Args() { title, startIndex, endIndex }: GetRecipesArgs) { - // sample implementation + // Example implementation let recipes = this.recipesCollection; if (title) { recipes = recipes.filter(recipe => recipe.title === title); @@ -155,23 +155,23 @@ type Query { ### Input types -GraphQL mutations can be similarly created: Declare the class method, use the `@Mutation` decorator, create arguments, provide a return type (if needed) etc. But for mutations we usually use `input` types, hence TypeGraphQL allows us to create inputs in the same way as [object types](types-and-fields.md) but by using the `@InputType()` decorator: +GraphQL mutations can be similarly created: Declare the class method, use the `@Mutation` decorator, create arguments, provide a return type (if needed) etc. But for mutations we usually use `input` types, hence TypeGraphQL allows us to create inputs in the same way as [object types](./types-and-fields.md) but by using the `@InputType()` decorator: -```typescript +```ts @InputType() class AddRecipeInput {} ``` To ensure we don't accidentally change the property type we leverage the TypeScript type checking system by implementing the `Partial` type: -```typescript +```ts @InputType() class AddRecipeInput implements Partial {} ``` We then declare any input fields we need, using the `@Field()` decorator: -```typescript +```ts @InputType({ description: "New recipe data" }) class AddRecipeInput implements Partial { @Field() @@ -186,13 +186,13 @@ After that we can use the `AddRecipeInput` type in our mutation. We can do this We may also need access to the context. To achieve this we use the `@Ctx()` decorator with the optional user-defined `Context` interface: -```typescript +```ts @Resolver() class RecipeResolver { // ... @Mutation() addRecipe(@Arg("data") newRecipeData: AddRecipeInput, @Ctx() ctx: Context): Recipe { - // sample implementation + // Example implementation const recipe = RecipesUtils.create(newRecipeData, ctx.user); this.recipesCollection.push(recipe); return recipe; @@ -225,20 +225,20 @@ Queries and mutations are not the only type of resolvers. We often create object Field resolvers in TypeGraphQL are very similar to queries and mutations - we create them as a method on the resolver class but with a few modifications. First we declare which object type fields we are resolving by providing the type to the `@Resolver` decorator: -```typescript +```ts @Resolver(of => Recipe) class RecipeResolver { - // queries and mutations + // Queries and mutations } ``` Then we create a class method that will become the field resolver. In our example we have the `averageRating` field in the `Recipe` object type that should calculate the average from the `ratings` array. -```typescript +```ts @Resolver(of => Recipe) class RecipeResolver { - // queries and mutations + // Queries and mutations averageRating(recipe: Recipe) { // ... @@ -248,10 +248,10 @@ class RecipeResolver { We then mark the method as a field resolver with the `@FieldResolver()` decorator. Since we've already defined the field type in the `Recipe` class definition, there's no need to redefine it. We also decorate the method parameters with the `@Root` decorator in order to inject the recipe object. -```typescript +```ts @Resolver(of => Recipe) class RecipeResolver { - // queries and mutations + // Queries and mutations @FieldResolver() averageRating(@Root() recipe: Recipe) { @@ -263,10 +263,10 @@ class RecipeResolver { For enhanced type safety we can implement the `ResolverInterface` interface. It's a small helper that checks if the return type of the field resolver methods, like `averageRating(...)`, matches the `averageRating` property of the `Recipe` class and whether the first parameter of the method is the actual object type (`Recipe` class). -```typescript +```ts @Resolver(of => Recipe) class RecipeResolver implements ResolverInterface { - // queries and mutations + // Queries and mutations @FieldResolver() averageRating(@Root() recipe: Recipe) { @@ -277,10 +277,10 @@ class RecipeResolver implements ResolverInterface { Here is the full implementation of the sample `averageRating` field resolver: -```typescript +```ts @Resolver(of => Recipe) class RecipeResolver implements ResolverInterface { - // queries and mutations + // Queries and mutations @FieldResolver() averageRating(@Root() recipe: Recipe) { @@ -292,7 +292,7 @@ class RecipeResolver implements ResolverInterface { For simple resolvers like `averageRating` or deprecated fields that behave like aliases, you can create field resolvers inline in the object type class definition: -```typescript +```ts @ObjectType() class Recipe { @Field() @@ -319,13 +319,14 @@ class Recipe { However, if the code is more complicated and has side effects (i.e. api calls, fetching data from a databases), a resolver class method should be used instead. This way we can leverage the dependency injection mechanism, which is really helpful in testing. For example: -```typescript +```ts import { Repository } from "typeorm"; @Resolver(of => Recipe) class RecipeResolver implements ResolverInterface { constructor( - private userRepository: Repository, // dependency injection + // Dependency injection + private readonly userRepository: Repository, ) {} @FieldResolver() @@ -341,7 +342,7 @@ Note that if a field name of a field resolver doesn't exist in the resolver obje ## Resolver Inheritance -Resolver class `inheritance` is an advanced topic covered in the [resolver inheritance docs](inheritance.md#resolvers-inheritance). +Resolver class `inheritance` is an advanced topic covered in the [resolver inheritance docs](./inheritance.md#resolvers-inheritance). ## Examples diff --git a/docs/scalars.md b/docs/scalars.md index de7275e8e..422512b16 100644 --- a/docs/scalars.md +++ b/docs/scalars.md @@ -12,8 +12,8 @@ TypeGraphQL provides aliases for 3 basic scalars: This shorthand allows you to save keystrokes when declaring field types: -```typescript -// import the aliases +```ts +// Import the aliases import { ID, Float, Int } from "type-graphql"; @ObjectType() @@ -33,7 +33,7 @@ In the last case you can omit the `type => Float` since JavaScript `Number` will Other scalars - i.e. `GraphQLString` and `GraphQLBoolean` - do not need aliases. When possible, they will be reflected automatically: -```typescript +```ts @ObjectType() class User { @Field() @@ -46,7 +46,7 @@ class User { However in some cases we must explicitly declare the string/bool scalar type. Use JS constructor functions (`String`, `Boolean`) then: -```typescript +```ts @ObjectType() class SampleObject { @Field(type => String, { nullable: true }) @@ -59,43 +59,13 @@ class SampleObject { } ``` -## Date Scalars - -TypeGraphQL provides built-in scalars for the `Date` type. There are two versions of this scalar: - -- timestamp based (`"timestamp"`) - `1518037458374` -- ISO format (`"isoDate"`) - `"2018-02-07T21:04:39.573Z"` - -They are exported from the `type-graphql` package as `GraphQLISODateTime` and `GraphQLTimestamp`. - -By default, TypeGraphQL uses the ISO date format, however you can change it in the `buildSchema` options: - -```typescript -import { buildSchema } from "type-graphql"; - -const schema = await buildSchema({ - resolvers, - dateScalarMode: "timestamp", // "timestamp" or "isoDate" -}); -``` - -There's no need then to explicitly declare the field type: - -```typescript -@ObjectType() -class User { - @Field() - registrationDate: Date; -} -``` - ## Custom Scalars TypeGraphQL also supports custom scalar types! First of all, we need to create our own `GraphQLScalarType` instance or import a scalar type from a 3rd-party npm library. For example, Mongo's ObjectId: -```typescript +```ts import { GraphQLScalarType, Kind } from "graphql"; import { ObjectId } from "mongodb"; @@ -103,38 +73,38 @@ export const ObjectIdScalar = new GraphQLScalarType({ name: "ObjectId", description: "Mongo object id scalar type", serialize(value: unknown): string { - // check the type of received value + // Check type of value if (!(value instanceof ObjectId)) { throw new Error("ObjectIdScalar can only serialize ObjectId values"); } - return value.toHexString(); // value sent to the client + return value.toHexString(); // Value sent to client }, parseValue(value: unknown): ObjectId { - // check the type of received value + // Check type of value if (typeof value !== "string") { throw new Error("ObjectIdScalar can only parse string values"); } - return new ObjectId(value); // value from the client input variables + return new ObjectId(value); // Value from client input variables }, parseLiteral(ast): ObjectId { - // check the type of received value + // Check type of value if (ast.kind !== Kind.STRING) { throw new Error("ObjectIdScalar can only parse string values"); } - return new ObjectId(ast.value); // value from the client query + return new ObjectId(ast.value); // Value from client query }, }); ``` Then we can just use it in our field decorators: -```typescript -// import the earlier created const +```ts +// Import earlier created const import { ObjectIdScalar } from "../my-scalars/ObjectId"; @ObjectType() class User { - @Field(type => ObjectIdScalar) // and explicitly use it + @Field(type => ObjectIdScalar) // Explicitly use it readonly id: ObjectId; @Field() @@ -147,17 +117,17 @@ class User { Optionally, we can declare the association between the reflected property type and our scalars to automatically map them (no need for explicit type annotation!): -```typescript +```ts @ObjectType() class User { - @Field() // magic goes here - no type annotation for custom scalar + @Field() // Magic goes here - no type annotation for custom scalar readonly id: ObjectId; } ``` All we need to do is register the association map in the `buildSchema` options: -```typescript +```ts import { ObjectId } from "mongodb"; import { ObjectIdScalar } from "../my-scalars/ObjectId"; import { buildSchema } from "type-graphql"; @@ -169,3 +139,35 @@ const schema = await buildSchema({ ``` However, we must be aware that this will only work when the TypeScript reflection mechanism can handle it. So our class property type must be a `class`, not an enum, union or interface. + +## Date Scalars + +TypeGraphQL provides built-in scalars for the `Date` type. There are two versions of this scalar: + +- ISO-formatted string: `"2023-05-19T21:04:39.573Z"` +- timestamp-based number: `1518037458374` + +They are exported from the `type-graphql` package as `GraphQLISODateTime` and `GraphQLTimestamp` but comes from `graphql-scalars` npm package. + +By default, TypeGraphQL uses the ISO date format, however we can change it to timestamp format using the mentioned above `scalarsMap` option of `buildSchema` configuration: + +```ts +import { buildSchema, GraphQLTimestamp } from "type-graphql"; + +const schema = await buildSchema({ + resolvers, + scalarsMap: [{ type: Date, scalar: GraphQLTimestamp }], +}); +``` + +There's no need then to explicitly declare the field type: + +```ts +@ObjectType() +class User { + @Field() + registrationDate: Date; +} +``` + +We can of course use any other `Date` scalar from `graphql-scalars` or any other npm package. diff --git a/docs/subscriptions.md b/docs/subscriptions.md index 3ef7b1f07..3c8efe1e4 100644 --- a/docs/subscriptions.md +++ b/docs/subscriptions.md @@ -4,15 +4,15 @@ title: Subscriptions GraphQL can be used to perform reads with queries and writes with mutations. However, oftentimes clients want to get updates pushed to them from the server when data they care about changes. -To support that, GraphQL has a third operation: subscription. TypeGraphQL of course has great support for subscription, using the [graphql-subscriptions](https://github.com/apollographql/graphql-subscriptions) package created by [Apollo GraphQL](https://www.apollographql.com/). +To support that, GraphQL has a third operation: subscription. TypeGraphQL of course has great support for subscription, using the [`@graphql-yoga/subscriptions`](https://the-guild.dev/graphql/yoga-server/docs/features/subscriptions) package created by [`The Guild`](https://the-guild.dev/). ## Creating Subscriptions -Subscription resolvers are similar to [queries and mutation resolvers](resolvers.md) but slightly more complicated. +Subscription resolvers are similar to [queries and mutation resolvers](./resolvers.md) but slightly more complicated. First we create a normal class method as always, but this time annotated with the `@Subscription()` decorator. -```typescript +```ts class SampleResolver { // ... @Subscription() @@ -24,13 +24,13 @@ class SampleResolver { Then we have to provide the topics we wish to subscribe to. This can be a single topic string, an array of topics or a function to dynamically create a topic based on subscription arguments passed to the query. We can also use TypeScript enums for enhanced type safety. -```typescript +```ts class SampleResolver { // ... @Subscription({ - topics: "NOTIFICATIONS", // single topic - topics: ["NOTIFICATIONS", "ERRORS"] // or topics array - topics: ({ args, payload, context }) => args.topic // or dynamic topic function + topics: "NOTIFICATIONS", // Single topic + topics: ["NOTIFICATIONS", "ERRORS"] // Or topics array + topics: ({ args, context }) => args.topic // Or dynamic topic function }) newNotification(): Notification { // ... @@ -41,7 +41,7 @@ class SampleResolver { We can also provide the `filter` option to decide which topic events should trigger our subscription. This function should return a `boolean` or `Promise` type. -```typescript +```ts class SampleResolver { // ... @Subscription({ @@ -56,13 +56,13 @@ class SampleResolver { We can also provide a custom subscription logic which might be useful, e.g. if we want to use the Prisma subscription functionality or something similar. -All we need to do is to use the the `subscribe` option which should be a function that returns an `AsyncIterator`. Example using Prisma client subscription feature: +All we need to do is to use the `subscribe` option which should be a function that returns an `AsyncIterable` or a `Promise`. Example using Prisma 1 subscription feature: -```typescript +```ts class SampleResolver { // ... @Subscription({ - subscribe: (root, args, context, info) => { + subscribe: ({ root, args, context, info }) => { return context.prisma.$subscribe.users({ mutation_in: [args.mutationType] }); }, }) @@ -72,11 +72,11 @@ class SampleResolver { } ``` -> Be aware that we can't mix the `subscribe` option with the `topics` and `filter` options. If the filtering is still needed, we can use the [`withFilter` function](https://github.com/apollographql/graphql-subscriptions#filters) from the `graphql-subscriptions` package. +> Be aware that we can't mix the `subscribe` option with the `topics` and `filter` options. If the filtering is still needed, we can use the [`filter` and `map` helpers](https://the-guild.dev/graphql/yoga-server/docs/features/subscriptions#filter-and-map-values) from the `@graphql-yoga/subscriptions` package. Now we can implement the subscription resolver. It will receive the payload from a triggered topic of the pubsub system using the `@Root()` decorator. There, we can transform it to the returned shape. -```typescript +```ts class SampleResolver { // ... @Subscription({ @@ -104,7 +104,7 @@ e.g. when we modify some resource that clients want to receive notifications abo So, let us assume we have this mutation for adding a new comment: -```typescript +```ts class SampleResolver { // ... @Mutation(returns => Boolean) @@ -116,87 +116,96 @@ class SampleResolver { } ``` -We use the `@PubSub()` decorator to inject the `pubsub` into our method params. -There we can trigger the topics and send the payload to all topic subscribers. +First, we need to create the `PubSub` instance. In most cases, we call `createPubSub()` function from `@graphql-yoga/subscriptions` package. Optionally, we can define the used topics and payload type using the type argument, e.g.: + +```ts +import { createPubSub } from "@graphql-yoga/subscriptions"; + +export const pubSub = createPubSub<{ + NOTIFICATIONS: [NotificationPayload]; + DYNAMIC_ID_TOPIC: [number, NotificationPayload]; +}>(); +``` + +Then, we need to register the `PubSub` instance in the `buildSchema()` function options: + +```ts +import { buildSchema } from "type-graphql"; +import { pubSub } from "./pubsub"; + +const schema = await buildSchema({ + resolver, + pubSub, +}); +``` + +Finally, we can use the created `PubSub` instance to trigger the topics and send the payload to all topic subscribers: + +```ts +import { pubSub } from "./pubsub"; -```typescript class SampleResolver { // ... @Mutation(returns => Boolean) async addNewComment(@Arg("comment") input: CommentInput, @PubSub() pubSub: PubSubEngine) { const comment = this.commentsService.createNew(input); await this.commentsRepository.save(comment); - // here we can trigger subscriptions topics + // Trigger subscriptions topics const payload: NotificationPayload = { message: input.content }; - await pubSub.publish("NOTIFICATIONS", payload); + pubSub.publish("NOTIFICATIONS", payload); return true; } } ``` -For easier testability (mocking/stubbing), we can also inject the `publish` method by itself bound to a selected topic. -This is done by using the `@PubSub("TOPIC_NAME")` decorator and the `Publisher` type: +And that's it! Now all subscriptions attached to the `NOTIFICATIONS` topic will be triggered when performing the `addNewComment` mutation. -```typescript -class SampleResolver { - // ... - @Mutation(returns => Boolean) - async addNewComment( - @Arg("comment") input: CommentInput, - @PubSub("NOTIFICATIONS") publish: Publisher, - ) { - const comment = this.commentsService.createNew(input); - await this.commentsRepository.save(comment); - // here we can trigger subscriptions topics - await publish({ message: input.content }); - return true; +## Topic with dynamic ID + +The idea of this feature is taken from the `@graphql-yoga/subscriptions` that is used under the hood. +Basically, sometimes you only want to emit and listen for events for a specific entity (e.g. user or product). Dynamic topic ID lets you declare topics scoped to a special identifier, e.g.: + +```ts +@Resolver() +class NotificationResolver { + @Subscription({ + topics: "NOTIFICATIONS", + topicId: ({ context }) => context.userId, + }) + newNotification(@Root() { message }: NotificationPayload): Notification { + return { message, date: new Date() }; } } ``` -And that's it! Now all subscriptions attached to the `NOTIFICATIONS` topic will be triggered when performing the `addNewComment` mutation. +Then in your mutation or services, you need to pass the topic id as the second parameter: -## Using a custom PubSub system +```ts +pubSub.publish("NOTIFICATIONS", userId, { id, message }); +``` -By default, TypeGraphQL uses a simple `PubSub` system from `grapqhl-subscriptions` which is based on EventEmitter. -This solution has a big drawback in that it will work correctly only when we have a single instance (process) of our Node.js app. +> Be aware that this feature must be supported by the pubsub system of your choice. +> If you decide to use something different than `createPubSub()` from `@graphql-yoga/subscriptions`, the second argument might be treated as a payload, not dynamic topic id. -For better scalability we'll want to use one of the [`PubSub implementations`](https://github.com/apollographql/graphql-subscriptions#pubsub-implementations) backed by an external store like Redis with the [`graphql-redis-subscriptions`](https://github.com/davidyaha/graphql-redis-subscriptions) package. +## Using a custom PubSub system -All we need to do is create an instance of PubSub according to the package instructions and then provide it to the TypeGraphQL `buildSchema` options: +While TypeGraphQL uses the `@graphql-yoga/subscriptions` package under the hood to handle subscription, there's no requirement to use that implementation of `PubSub`. -```typescript -const myRedisPubSub = getConfiguredRedisPubSub(); +In fact, you can use any pubsub system you want, not only the `graphql-yoga` one. +The only requirement is to comply with the exported `PubSub` interface - having proper `.subscribe()` and `.publish()` methods. -const schema = await buildSchema({ - resolvers: [__dirname + "/**/*.resolver.ts"], - pubSub: myRedisPubSub, -}); -``` +This is especially helpful for production usage, where we can't rely on the in-memory event emitter, so that we [use distributed pubsub](https://the-guild.dev/graphql/yoga-server/docs/features/subscriptions#distributed-pubsub-for-production). ## Creating a Subscription Server -The [bootstrap guide](bootstrap.md) and all the earlier examples used [`apollo-server`](https://github.com/apollographql/apollo-server) to create an HTTP endpoint for our GraphQL API. - -Fortunately, to make subscriptions work, we don't need to manually provide a transport layer that doesn't have constraints of HTTP and can do a push-based communication (WebSockets). -The `apollo-server` package has built-in subscriptions support using websockets, so it works out of the box without any changes to our bootstrap config. However, if we want, we can provide the `subscriptions` property of the config object: - -```typescript -// Create GraphQL server -const server = new ApolloServer({ - schema, - subscriptions: { - path: "/subscriptions", - // other options and hooks, like `onConnect` - }, -}); -``` +The [bootstrap guide](./bootstrap.md) and all the earlier examples used [`apollo-server`](https://github.com/apollographql/apollo-server) to create an HTTP endpoint for our GraphQL API. -And it's done! We have a working GraphQL subscription server on `/subscriptions`, along with the normal HTTP GraphQL server. +However, beginning in Apollo Server 3, subscriptions are not supported by the "batteries-included" apollo-server package. To enable subscriptions, you need to follow the guide on their docs page: + ## Examples -See how subscriptions work in a [simple example](https://github.com/MichalLytek/type-graphql/tree/master/examples/simple-subscriptions). +See how subscriptions work in a [simple example](https://github.com/MichalLytek/type-graphql/tree/master/examples/simple-subscriptions). You can see there, how simple is setting up GraphQL subscriptions using `graphql-yoga` package. For production usage, it's better to use something more scalable like a Redis-based pubsub system - [a working example is also available](https://github.com/MichalLytek/type-graphql/tree/master/examples/redis-subscriptions). However, to launch this example you need to have a running instance of Redis and you might have to modify the example code to provide your connection parameters. diff --git a/docs/types-and-fields.md b/docs/types-and-fields.md index 1cf2502d0..1736d5a90 100644 --- a/docs/types-and-fields.md +++ b/docs/types-and-fields.md @@ -6,7 +6,7 @@ The main idea of TypeGraphQL is to automatically create GraphQL schema definitio Let's start by defining our example TypeScript class which represents our `Recipe` model with fields for storing the recipe data: -```typescript +```ts class Recipe { id: string; title: string; @@ -17,7 +17,7 @@ class Recipe { The first thing we must do is decorate the class with the `@ObjectType` decorator. It marks the class as the `type` known from the GraphQL SDL or `GraphQLObjectType` from `graphql-js`: -```typescript +```ts @ObjectType() class Recipe { id: string; @@ -30,7 +30,7 @@ class Recipe { Then we declare which class properties should be mapped to the GraphQL fields. To do this, we use the `@Field` decorator, which is also used to collect metadata from the TypeScript reflection system: -```typescript +```ts @ObjectType() class Recipe { @Field() @@ -58,13 +58,13 @@ So for nullable properties like `averageRating` which might not be defined when In the case of lists, we may also need to define their nullability in a more detailed form. The basic `{ nullable: true | false }` setting only applies to the whole list (`[Item!]` or `[Item!]!`), so if we need a sparse array, we can control the list items' nullability via `nullable: "items"` (for `[Item]!`) or `nullable: "itemsAndList"` (for the `[Item]`) option. Be aware that setting `nullableByDefault: true` option will also apply to lists, so it will produce `[Item]` type, just like with `nullable: "itemsAndList"`. -For nested lists, those options apply to the whole depth of the array: `@Field(() => [[Item]]` would by defaut produce `[[Item!]!]!`, setting `nullable: "itemsAndList"` would produce `[[Item]]` while `nullable: "items"` would produce `[[Item]]!` +For nested lists, those options apply to the whole depth of the array: `@Field(() => [[Item]]` would by default produce `[[Item!]!]!`, setting `nullable: "itemsAndList"` would produce `[[Item]]` while `nullable: "items"` would produce `[[Item]]!` In the config object we can also provide the `description` and `deprecationReason` properties for GraphQL schema purposes. So after these changes our example class would look like this: -```typescript +```ts @ObjectType({ description: "The recipe model" }) class Recipe { @Field(type => ID) @@ -94,7 +94,7 @@ type Recipe { Similarly, the `Rate` type class would look like this: -```typescript +```ts @ObjectType() class Rate { @Field(type => Int) @@ -116,18 +116,18 @@ type Rate { } ``` -As we can see, for the `id` property of `Recipe` we passed `type => ID` and for the `value` field of `Rate` we passed `type => Int`. This way we can overwrite the inferred type from the reflection metadata. We can read more about the ID and Int scalars in [the scalars docs](scalars.md). There is also a section about the built-in `Date` scalar. +As we can see, for the `id` property of `Recipe` we passed `type => ID` and for the `value` field of `Rate` we passed `type => Int`. This way we can overwrite the inferred type from the reflection metadata. We can read more about the ID and Int scalars in [the scalars docs](./scalars.md). There is also a section about the built-in `Date` scalar. Also the `user` property doesn't have a `@Field()` decorator - this way we can hide some properties of our data model. In this case, we need to store the `user` field of the `Rate` object to the database in order to prevent multiple rates, but we don't want to make it publicly accessible. -Note that if a field of an object type is purely calculable (e.g. `averageRating` from `ratings` array) and we don't want to pollute the class signature, we can omit it and just implement the field resolver (described in [resolvers doc](resolvers.md)). +Note that if a field of an object type is purely calculable (e.g. `averageRating` from `ratings` array) and we don't want to pollute the class signature, we can omit it and just implement the field resolver (described in [resolvers doc](./resolvers.md)). Be aware that **defining constructors is strictly forbidden** and we shouldn't use them there, as TypeGraphQL creates instances of object type classes under the hood by itself. In some case we may want to expose our classes or properties under a different types or fields name. To accomplish this, we can use the `name` parameter or `name` property of decorator's options, e.g.: -```typescript +```ts @ObjectType("ExternalTypeName") class InternalClassName { @Field({ name: "externalFieldName" }) diff --git a/docs/unions.md b/docs/unions.md index b8e129980..098b4aaf1 100644 --- a/docs/unions.md +++ b/docs/unions.md @@ -10,7 +10,7 @@ Read more about the GraphQL Union Type in the [official GraphQL docs](http://gra Let's start by creating the object types from the example above: -```typescript +```ts @ObjectType() class Movie { @Field() @@ -21,7 +21,7 @@ class Movie { } ``` -```typescript +```ts @ObjectType() class Actor { @Field() @@ -34,11 +34,11 @@ class Actor { Now let's create an union type from the object types above - the rarely seen `[ ] as const` syntax is to inform TypeScript compiler that it's a tuple, which allows for better TS union type inference: -```typescript +```ts import { createUnionType } from "type-graphql"; const SearchResultUnion = createUnionType({ - name: "SearchResult", // the name of the GraphQL union + name: "SearchResult", // Name of the GraphQL union types: () => [Movie, Actor] as const, // function that returns tuple of object types classes }); ``` @@ -47,7 +47,7 @@ Then we can use the union type in the query by providing the `SearchResultUnion` Notice, that we have to explicitly use the decorator return type annotation due to TypeScript's reflection limitations. For TypeScript compile-time type safety we can also use `typeof SearchResultUnion` which is equal to type `Movie | Actor`. -```typescript +```ts @Resolver() class SearchResolver { @Query(returns => [SearchResultUnion]) @@ -66,17 +66,17 @@ Be aware that when the query/mutation return type (or field type) is a union, we However, we can also provide our own `resolveType` function implementation to the `createUnionType` options. This way we can return plain objects in resolvers and then determine the returned object type by checking the shape of the data object, e.g.: -```typescript +```ts const SearchResultUnion = createUnionType({ name: "SearchResult", types: () => [Movie, Actor] as const, - // our implementation of detecting returned object type + // Implementation of detecting returned object type resolveType: value => { if ("rating" in value) { - return Movie; // we can return object type class (the one with `@ObjectType()`) + return Movie; // Return object type class (the one with `@ObjectType()`) } if ("age" in value) { - return "Actor"; // or the schema name of the type as a string + return "Actor"; // Or the schema name of the type as a string } return undefined; }, @@ -89,12 +89,12 @@ const SearchResultUnion = createUnionType({ query { search(phrase: "Holmes") { ... on Actor { - # maybe Katie Holmes? + # Maybe Katie Holmes? name age } ... on Movie { - # for sure Sherlock Holmes! + # For sure Sherlock Holmes! name rating } diff --git a/docs/validation.md b/docs/validation.md index 948e5a795..b6a4e8be0 100644 --- a/docs/validation.md +++ b/docs/validation.md @@ -5,21 +5,27 @@ sidebar_label: Validation ## Scalars -The standard way to ensure that inputs and arguments are correct, such as an `email` field that really contains a proper e-mail address, is to use [custom scalars](https://github.com/MichalLytek/type-graphql/blob/master/docs/scalars.md) e.g. `GraphQLEmail` from [`graphql-custom-types`](https://github.com/stylesuxx/graphql-custom-types). However, creating scalars for all single cases of data types (credit card number, base64, IP, URL) might be cumbersome. +The standard way to ensure that inputs and arguments are correct, such as an `email` field that really contains a proper e-mail address, is to use [custom scalars](./scalars.md) e.g. `GraphQLEmail` from [`graphql-custom-types`](https://github.com/stylesuxx/graphql-custom-types). However, creating scalars for all single cases of data types (credit card number, base64, IP, URL) might be cumbersome. That's why TypeGraphQL has built-in support for argument and input validation. By default, we can use the [`class-validator`](https://github.com/typestack/class-validator) library and easily declare the requirements for incoming data (e.g. a number is in the range 0-255 or a password that is longer than 8 characters) thanks to the awesomeness of decorators. -We can also use other libraries or our own custom solution, as described in [custom validators](#custom-validators) section. +We can also use other libraries or our own custom solution, as described in [custom validators](#custom-validator) section. ## `class-validator` ### How to use -First we decorate the input/arguments class with the appropriate decorators from `class-validator`. +First, we need to install the `class-validator` package: + +```sh +npm install class-validator +``` + +Then we decorate the input/arguments class with the appropriate decorators from `class-validator`. So we take this: -```typescript +```ts @InputType() export class RecipeInput { @Field() @@ -32,7 +38,7 @@ export class RecipeInput { ...and turn it into this: -```typescript +```ts import { MaxLength, Length } from "class-validator"; @InputType() @@ -47,16 +53,25 @@ export class RecipeInput { } ``` +Then we need to enable the auto-validate feature (as it's disabled by default) by simply setting `validate: true` in `buildSchema` options, e.g.: + +```ts +const schema = await buildSchema({ + resolvers: [RecipeResolver], + validate: true, // Enable 'class-validator' integration +}); +``` + And that's it! πŸ˜‰ TypeGraphQL will automatically validate our inputs and arguments based on the definitions: -```typescript +```ts @Resolver(of => Recipe) export class RecipeResolver { @Mutation(returns => Recipe) async addRecipe(@Arg("input") recipeInput: RecipeInput): Promise { - // you can be 100% sure that the input is correct + // 100% sure that the input is correct console.assert(recipeInput.title.length <= 30); console.assert(recipeInput.description.length >= 30); console.assert(recipeInput.description.length <= 255); @@ -68,16 +83,16 @@ Of course, [there are many more decorators](https://github.com/typestack/class-v This feature is enabled by default. However, we can disable it if we must: -```typescript +```ts const schema = await buildSchema({ resolvers: [RecipeResolver], - validate: false, // disable automatic validation or pass the default config object + validate: false, // Disable automatic validation or pass the default config object }); ``` And we can still enable it per resolver's argument if we need to: -```typescript +```ts class RecipeResolver { @Mutation(returns => Recipe) async addRecipe(@Arg("input", { validate: true }) recipeInput: RecipeInput) { @@ -88,7 +103,7 @@ class RecipeResolver { The `ValidatorOptions` object used for setting features like [validation groups](https://github.com/typestack/class-validator#validation-groups) can also be passed: -```typescript +```ts class RecipeResolver { @Mutation(returns => Recipe) async addRecipe( @@ -101,6 +116,7 @@ class RecipeResolver { ``` Note that by default, the `skipMissingProperties` setting of the `class-validator` is set to `true` because GraphQL will independently check whether the params/fields exist or not. +Same goes to `forbidUnknownValues` setting which is set to `false` because the GraphQL runtime checks for additional data, not described in schema. GraphQL will also check whether the fields have correct types (String, Int, Float, Boolean, etc.) so we don't have to use the `@IsOptional`, `@Allow`, `@IsString` or the `@IsInt` decorators at all! @@ -114,7 +130,7 @@ When a client sends incorrect data to the server: mutation ValidationMutation { addRecipe( input: { - # too long! + # Too long! title: "Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet" } ) { @@ -126,7 +142,7 @@ mutation ValidationMutation { the [`ArgumentValidationError`](https://github.com/MichalLytek/type-graphql/blob/master/src/errors/ArgumentValidationError.ts) will be thrown. -By default, the `apollo-server` package from the [bootstrap guide](bootstrap.md) will format the error to match the `GraphQLFormattedError` interface. So when the `ArgumentValidationError` occurs, the client will receive this JSON with a nice `validationErrors` property inside of `extensions.exception`: +By default, the `apollo-server` package from the [bootstrap guide](./bootstrap.md) will format the error to match the `GraphQLFormattedError` interface. So when the `ArgumentValidationError` occurs, the client will receive this JSON with a nice `validationErrors` property inside of `extensions.exception`: ```json { @@ -158,9 +174,9 @@ By default, the `apollo-server` package from the [bootstrap guide](bootstrap.md) ], "stacktrace": [ "Error: Argument Validation Error", - " at Object. (F:\\#Projekty\\type-graphql\\src\\resolvers\\validate-arg.ts:29:11)", + " at Object. (/type-graphql/src/resolvers/validate-arg.ts:29:11)", " at Generator.throw ()", - " at rejected (F:\\#Projekty\\type-graphql\\node_modules\\tslib\\tslib.js:105:69)", + " at rejected (/type-graphql/node_modules/tslib/tslib.js:105:69)", " at processTicksAndRejections (internal/process/next_tick.js:81:5)" ] } @@ -173,7 +189,7 @@ By default, the `apollo-server` package from the [bootstrap guide](bootstrap.md) Of course we can also create our own custom implementation of the `formatError` function provided in the `ApolloServer` config options which will transform the `GraphQLError` with a `ValidationError` array in the desired output format (e.g. `extensions.code = "ARGUMENT_VALIDATION_ERROR"`). -### Example +### Automatic Validation Example To see how this works, check out the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/master/examples/automatic-validation). @@ -187,33 +203,54 @@ An alternative solution that allows to completely get rid off big `class-validat We can also use other libraries than `class-validator` together with TypeGraphQL. -To integrate it, all we need to do is to provide a custom function as `validate` option in `buildSchema`. -It receives two parameters: +To integrate it, all we need to do is to provide a custom function. +It receives three parameters: - `argValue` which is the injected value of `@Arg()` or `@Args()` -- `argType` which is a runtime type information (e.g. `String` or `RecipeInput`). +- `argType` which is a runtime type information (e.g. `String` or `RecipeInput`) +- `resolverData` which holds the resolver execution context, described as generic type `ResolverData` -The `validate` function can be async and should return nothing (`void`) when validation passes or throw an error when validation fails. -So be aware of this while trying to wrap another library in `validate` function for TypeGraphQL. +This function can be an async function and should return nothing (`void`) when validation passes, or throw an error when validation fails. +So be aware of this while trying to wrap another library in `validateFn` function for TypeGraphQL. +Then we provide this function as a `validateFn` option in `buildSchema`. Example using [decorators library for Joi validators (`joiful`)](https://github.com/joiful-ts/joiful): ```ts const schema = await buildSchema({ - // ...other options - validate: argValue => { - // call joiful validate + // ... + validateFn: argValue => { + // Call joiful validate const { error } = joiful.validate(argValue); if (error) { - // throw error on failed validation + // Throw error on failed validation throw error; } }, }); ``` +The `validateFn` option is also supported as a `@Arg()` or `@Args()` decorator option, e.g.: + +```ts +@Resolver() +class SampleResolver { + @Query() + sampleQuery( + @Arg("sampleArg", { + validateFn: (argValue, argType) => { + // Do something here with arg value and type... + }, + }) + sampleArg: string, + ): string { + // ... + } +} +``` + > Be aware that when using custom validator, the error won't be wrapped with `ArgumentValidationError` like for the built-in `class-validator` validation. -### Example +### Custom Validation Example To see how this works, check out the [simple custom validation integration example](https://github.com/MichalLytek/type-graphql/tree/master/examples/custom-validation). diff --git a/examples/.eslintrc b/examples/.eslintrc new file mode 100644 index 000000000..69bbd09ef --- /dev/null +++ b/examples/.eslintrc @@ -0,0 +1,8 @@ +{ + "rules": { + "no-console": "off", + "class-methods-use-this": "off", + "import/no-cycle": "off", + "import/no-extraneous-dependencies": ["error", { "devDependencies": true }] + } +} diff --git a/examples/README.md b/examples/README.md index f4b25ab24..935b1b01a 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,8 +1,10 @@ # Examples -This folder consist of simple examples showing how to use different `TypeGraphQL` features and how well it integrates with 3rd party libraries. +This folder consists of simple examples showing how to use different `TypeGraphQL` features and how well it integrates with 3rd party libraries. -All examples has a `examples.gql` file with sample queries/mutations/subscriptions that you can execute. +To run an example, simply go to the subdirectory (e.g. `cd ./simple-usage`), and then start the server (`npx ts-node ./index.ts`). + +Each subdirectory contains a `examples.graphql` file with predefined GraphQL queries/mutations/subscriptions that you can use in Apollo Studio () and play with them by modifying their shape and data. > **Note**: Be aware that the examples on master branch are designed to work with latest codebase that might not be released yet. > So if you are looking for examples that are compatible with the version you use, just browse the files by the git tag, e.g. [`tree/v0.16.0` for `0.16.0` release](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples). @@ -15,7 +17,7 @@ All examples has a `examples.gql` file with sample queries/mutations/subscriptio - [Enums and unions](./enums-and-unions) - [Subscriptions (simple)](./simple-subscriptions) -- [Subscriptions (using Redis)](./redis-subscriptions) +- [Subscriptions (using Redis) \*\*](./redis-subscriptions) - [Interfaces](./interfaces-inheritance) - [Extensions (metadata)](./extensions) @@ -37,11 +39,13 @@ All examples has a `examples.gql` file with sample queries/mutations/subscriptio - [TypeORM (manual, synchronous) \*](./typeorm-basic-usage) - [TypeORM (automatic, lazy relations) \*](./typeorm-lazy-relations) -- [MikroORM](./mikro-orm) -- [Typegoose](./typegoose) -- [Apollo federation](./apollo-federation) +- [MikroORM \*](./mikro-orm) +- [Typegoose \*](./typegoose) +- [Apollo Federation](./apollo-federation) +- [Apollo Federation 2](./apollo-federation-2) - [Apollo Cache Control](./apollo-cache) -- [Apollo Client state](./apollo-client) -- [GraphQL Modules](./graphql-modules) +- [GraphQL Scalars](./graphql-scalars) +- [TSyringe](./tsyringe) -_\* Note that you need to edit the TypeORM examples `index.ts` with credentials to your local database_ +_\* Note that we need to provide the environment variable `DATABASE_URL` with connection parameters to your local database_ \ +_\*\* Note that we need to provide the environment variable `REDIS_URL` with connection parameters to your local Redis instance_ diff --git a/examples/apollo-cache/cache-control.ts b/examples/apollo-cache/cache-control.ts index a79e3eb47..c06ffb03d 100644 --- a/examples/apollo-cache/cache-control.ts +++ b/examples/apollo-cache/cache-control.ts @@ -1,13 +1,14 @@ -import { CacheHint } from "apollo-cache-control"; -import { Directive } from "../../src"; +import { type CacheHint } from "@apollo/cache-control-types"; +import { Directive } from "type-graphql"; +import { type RequireAtLeastOne } from "./helpers/RequireAtLeastOne"; -export function CacheControl({ maxAge, scope }: CacheHint) { - if (!maxAge && !scope) { +export function CacheControl({ maxAge, scope }: RequireAtLeastOne) { + if (maxAge === undefined && scope === undefined) { throw new Error("Missing maxAge or scope param for @CacheControl"); } let sdl = "@cacheControl("; - if (maxAge) { + if (maxAge !== undefined) { sdl += `maxAge: ${maxAge}`; } if (scope) { diff --git a/examples/apollo-cache/examples.gql b/examples/apollo-cache/examples.graphql similarity index 100% rename from examples/apollo-cache/examples.gql rename to examples/apollo-cache/examples.graphql diff --git a/examples/apollo-cache/helpers/RequireAtLeastOne.d.ts b/examples/apollo-cache/helpers/RequireAtLeastOne.d.ts new file mode 100644 index 000000000..1e7781db3 --- /dev/null +++ b/examples/apollo-cache/helpers/RequireAtLeastOne.d.ts @@ -0,0 +1,6 @@ +// https://stackoverflow.com/a/49725198/6676781 + +export type RequireAtLeastOne = Pick> & + { + [K in Keys]-?: Required> & Partial>>; + }[Keys]; diff --git a/examples/apollo-cache/utils.ts b/examples/apollo-cache/helpers/getTime.ts similarity index 100% rename from examples/apollo-cache/utils.ts rename to examples/apollo-cache/helpers/getTime.ts diff --git a/examples/apollo-cache/index.ts b/examples/apollo-cache/index.ts index 5eed2b4c1..4ab836375 100644 --- a/examples/apollo-cache/index.ts +++ b/examples/apollo-cache/index.ts @@ -1,26 +1,35 @@ import "reflect-metadata"; -import { ApolloServer } from "apollo-server"; -import responseCachePlugin from "apollo-server-plugin-response-cache"; -import { buildSchema } from "../../src"; - -import { RecipeResolver } from "./recipe-resolver"; +import path from "node:path"; +import { ApolloServer } from "@apollo/server"; +import { ApolloServerPluginCacheControl } from "@apollo/server/plugin/cacheControl"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import responseCachePlugin from "@apollo/server-plugin-response-cache"; +import { buildSchema } from "type-graphql"; +import { RecipeResolver } from "./recipe.resolver"; async function bootstrap() { + // Build TypeGraphQL executable schema const schema = await buildSchema({ + // Array of resolvers resolvers: [RecipeResolver], + // Create 'schema.graphql' file with schema definition in current directory + emitSchemaFile: path.resolve(__dirname, "schema.graphql"), }); + // Create GraphQL server const server = new ApolloServer({ schema, - tracing: true, - // turn on cache headers - cacheControl: true, - // add in-memory cache plugin - plugins: [responseCachePlugin()], + plugins: [ + // Cache headers + ApolloServerPluginCacheControl(), + // In-memory cache + responseCachePlugin(), + ], }); - const { url } = await server.listen(4000); - console.log(`Server is running, GraphQL Playground available at ${url}`); + // Start server + const { url } = await startStandaloneServer(server, { listen: { port: 4000 } }); + console.log(`GraphQL server ready at ${url}`); } -bootstrap(); +bootstrap().catch(console.error); diff --git a/examples/apollo-cache/recipe-resolver.ts b/examples/apollo-cache/recipe-resolver.ts deleted file mode 100644 index a76efb1e0..000000000 --- a/examples/apollo-cache/recipe-resolver.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Resolver, Query, Arg } from "../../src"; - -import { Recipe } from "./recipe-type"; -import { createRecipeSamples } from "./recipe-samples"; -import { CacheControl } from "./cache-control"; -import { getTime } from "./utils"; - -@Resolver(of => Recipe) -export class RecipeResolver { - private readonly items: Recipe[] = createRecipeSamples(); - - @Query(returns => Recipe, { nullable: true }) - async recipe(@Arg("title") title: string): Promise { - console.log(`Called 'recipe' with title '${title}' on ${getTime()}`); - return await this.items.find(recipe => recipe.title === title); - } - - @Query(returns => Recipe, { nullable: true }) - // here we declare that we want to cache the query for 60s - @CacheControl({ maxAge: 60 }) - async cachedRecipe(@Arg("title") title: string): Promise { - console.log(`Called 'cachedRecipe' with title '${title}' on ${getTime()}`); - return await this.items.find(recipe => recipe.title === title); - } - - @Query(returns => [Recipe]) - async recipes(): Promise { - return await this.items; - } -} diff --git a/examples/simple-usage/recipe-samples.ts b/examples/apollo-cache/recipe.data.ts similarity index 93% rename from examples/simple-usage/recipe-samples.ts rename to examples/apollo-cache/recipe.data.ts index 2288d1f8d..31ca8212d 100644 --- a/examples/simple-usage/recipe-samples.ts +++ b/examples/apollo-cache/recipe.data.ts @@ -1,28 +1,28 @@ -import { Recipe } from "./recipe-type"; +import { Recipe } from "./recipe.type"; + +function createRecipe(recipeData: Partial) { + return Object.assign(new Recipe(), recipeData); +} export function createRecipeSamples() { return [ createRecipe({ - description: "Desc 1", title: "Recipe 1", + description: "Desc 1", ratings: [0, 3, 1], creationDate: new Date("2018-04-11"), }), createRecipe({ - description: "Desc 2", title: "Recipe 2", + description: "Desc 2", ratings: [4, 2, 3, 1], creationDate: new Date("2018-04-15"), }), createRecipe({ - description: "Desc 3", title: "Recipe 3", + description: "Desc 3", ratings: [5, 4], creationDate: new Date(), }), ]; } - -function createRecipe(recipeData: Partial) { - return Object.assign(new Recipe(), recipeData); -} diff --git a/examples/apollo-cache/recipe.resolver.ts b/examples/apollo-cache/recipe.resolver.ts new file mode 100644 index 000000000..581100982 --- /dev/null +++ b/examples/apollo-cache/recipe.resolver.ts @@ -0,0 +1,29 @@ +import { Arg, Query, Resolver } from "type-graphql"; +import { CacheControl } from "./cache-control"; +import { getTime } from "./helpers/getTime"; +import { createRecipeSamples } from "./recipe.data"; +import { Recipe } from "./recipe.type"; + +@Resolver(_of => Recipe) +export class RecipeResolver { + private readonly items: Recipe[] = createRecipeSamples(); + + @Query(_returns => Recipe, { nullable: true }) + async recipe(@Arg("title") title: string): Promise { + console.log(`Called 'recipe' with title '${title}' on ${getTime()}`); + return this.items.find(recipe => recipe.title === title); + } + + @Query(_returns => Recipe, { nullable: true }) + // Cache query for 60s + @CacheControl({ maxAge: 60 }) + async cachedRecipe(@Arg("title") title: string): Promise { + console.log(`Called 'cachedRecipe' with title '${title}' on ${getTime()}`); + return this.items.find(recipe => recipe.title === title); + } + + @Query(_returns => [Recipe]) + async recipes(): Promise { + return this.items; + } +} diff --git a/examples/apollo-cache/recipe-type.ts b/examples/apollo-cache/recipe.type.ts similarity index 65% rename from examples/apollo-cache/recipe-type.ts rename to examples/apollo-cache/recipe.type.ts index f4370d8c6..60323e1e4 100644 --- a/examples/apollo-cache/recipe-type.ts +++ b/examples/apollo-cache/recipe.type.ts @@ -1,32 +1,30 @@ -import { Field, ObjectType, Int, Float } from "../../src"; - +import { Field, Float, Int, ObjectType } from "type-graphql"; import { CacheControl } from "./cache-control"; -import { getTime } from "./utils"; +import { getTime } from "./helpers/getTime"; @ObjectType() export class Recipe { @Field() - title: string; + title!: string; @Field({ nullable: true }) description?: string; - @Field(type => [Int]) - ratings: number[]; + @Field(_type => [Int]) + ratings!: number[]; @Field() - creationDate: Date; + creationDate!: Date; - @Field(type => Float, { nullable: true }) - // will invalidate `cachedRecipe` cache with maxAge of 60 to 10 - // if the field is requested + @Field(_type => Float, { nullable: true }) + // Invalidate 'cachedRecipe' cache with maxAge of 60 to 10 (if requested) @CacheControl({ maxAge: 10 }) get cachedAverageRating() { console.log(`Called 'cachedAverageRating' for recipe '${this.title}' on ${getTime()}`); return this.averageRating; } - @Field(type => Float, { nullable: true }) + @Field(_type => Float, { nullable: true }) get averageRating(): number | null { console.log(`Called 'averageRating' for recipe '${this.title}' on ${getTime()}`); const ratingsCount = this.ratings.length; @@ -34,6 +32,7 @@ export class Recipe { return null; } const ratingsSum = this.ratings.reduce((a, b) => a + b, 0); + return ratingsSum / ratingsCount; } } diff --git a/examples/apollo-cache/schema.graphql b/examples/apollo-cache/schema.graphql new file mode 100644 index 000000000..607f3608e --- /dev/null +++ b/examples/apollo-cache/schema.graphql @@ -0,0 +1,24 @@ +# ----------------------------------------------- +# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!! +# !!! DO NOT MODIFY THIS FILE BY YOURSELF !!! +# ----------------------------------------------- + +""" +A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar.This scalar is serialized to a string in ISO 8601 format and parsed from a string in ISO 8601 format. +""" +scalar DateTimeISO + +type Query { + cachedRecipe(title: String!): Recipe + recipe(title: String!): Recipe + recipes: [Recipe!]! +} + +type Recipe { + averageRating: Float + cachedAverageRating: Float + creationDate: DateTimeISO! + description: String + ratings: [Int!]! + title: String! +} diff --git a/examples/apollo-client/mocks/empty-module.js b/examples/apollo-client/mocks/empty-module.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/apollo-client/mocks/utils.js b/examples/apollo-client/mocks/utils.js deleted file mode 100644 index b82d148d0..000000000 --- a/examples/apollo-client/mocks/utils.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - promisify: () => {}, -}; diff --git a/examples/apollo-client/package-lock.json b/examples/apollo-client/package-lock.json deleted file mode 100644 index 1b80028a8..000000000 --- a/examples/apollo-client/package-lock.json +++ /dev/null @@ -1,7073 +0,0 @@ -{ - "requires": true, - "lockfileVersion": 1, - "dependencies": { - "@apollo/react-common": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@apollo/react-common/-/react-common-3.1.3.tgz", - "integrity": "sha512-Q7ZjDOeqjJf/AOGxUMdGxKF+JVClRXrYBGVq+SuVFqANRpd68MxtVV2OjCWavsFAN0eqYnRqRUrl7vtUCiJqeg==", - "requires": { - "ts-invariant": "^0.4.4", - "tslib": "^1.10.0" - } - }, - "@apollo/react-components": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@apollo/react-components/-/react-components-3.1.3.tgz", - "integrity": "sha512-H0l2JKDQMz+LkM93QK7j3ThbNXkWQCduN3s3eKxFN3Rdg7rXsrikJWvx2wQ868jmqy0VhwJbS1vYdRLdh114uQ==", - "requires": { - "@apollo/react-common": "^3.1.3", - "@apollo/react-hooks": "^3.1.3", - "prop-types": "^15.7.2", - "ts-invariant": "^0.4.4", - "tslib": "^1.10.0" - } - }, - "@apollo/react-hoc": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@apollo/react-hoc/-/react-hoc-3.1.3.tgz", - "integrity": "sha512-oCPma0uBVPTcYTR5sOvtMbpaWll4xDBvYfKr6YkDorUcQVeNzFu1LK1kmQjJP64bKsaziKYji5ibFaeCnVptmA==", - "requires": { - "@apollo/react-common": "^3.1.3", - "@apollo/react-components": "^3.1.3", - "hoist-non-react-statics": "^3.3.0", - "ts-invariant": "^0.4.4", - "tslib": "^1.10.0" - } - }, - "@apollo/react-hooks": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@apollo/react-hooks/-/react-hooks-3.1.3.tgz", - "integrity": "sha512-reIRO9xKdfi+B4gT/o/hnXuopUnm7WED/ru8VQydPw+C/KG/05Ssg1ZdxFKHa3oxwiTUIDnevtccIH35POanbA==", - "requires": { - "@apollo/react-common": "^3.1.3", - "@wry/equality": "^0.1.9", - "ts-invariant": "^0.4.4", - "tslib": "^1.10.0" - } - }, - "@apollo/react-ssr": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@apollo/react-ssr/-/react-ssr-3.1.3.tgz", - "integrity": "sha512-fUTmEYHxSTX1GA43B8vICxXXplpcEBnDwn0IgdAc3eG0p2YK97ZrJDRFCJ5vD7fyDZsrYhMf+rAI3sd+H2SS+A==", - "requires": { - "@apollo/react-common": "^3.1.3", - "@apollo/react-hooks": "^3.1.3", - "tslib": "^1.10.0" - } - }, - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/core": { - "version": "7.7.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.5.tgz", - "integrity": "sha512-M42+ScN4+1S9iB6f+TL7QBpoQETxbclx+KNoKJABghnKYE+fMzSGqst0BZJc8CpI625bwPwYgUyRvxZ+0mZzpw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.4", - "@babel/helpers": "^7.7.4", - "@babel/parser": "^7.7.5", - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "json5": "^2.1.0", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "json5": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", - "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", - "dev": true, - "requires": { - "minimist": "^1.2.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 - } - } - }, - "@babel/generator": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.4.tgz", - "integrity": "sha512-m5qo2WgdOJeyYngKImbkyQrnUN1mPceaG5BV+G0E3gWsa4l/jCSryWJdM2x8OuGAOyh+3d5pVYfZWCiNFtynxg==", - "dev": true, - "requires": { - "@babel/types": "^7.7.4", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.7.4.tgz", - "integrity": "sha512-2BQmQgECKzYKFPpiycoF9tlb5HA4lrVyAmLLVK177EcQAqjVLciUb2/R+n1boQ9y5ENV3uz2ZqiNw7QMBBw1Og==", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.7.4.tgz", - "integrity": "sha512-Biq/d/WtvfftWZ9Uf39hbPBYDUo986m5Bb4zhkeYDGUllF43D+nUe5M6Vuo6/8JDK/0YX/uBdeoQpyaNhNugZQ==", - "dev": true, - "requires": { - "@babel/helper-explode-assignable-expression": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-builder-react-jsx": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.7.4.tgz", - "integrity": "sha512-kvbfHJNN9dg4rkEM4xn1s8d1/h6TYNvajy9L1wx4qLn9HFg0IkTsQi4rfBe92nxrPUFcMsHoMV+8rU7MJb3fCA==", - "dev": true, - "requires": { - "@babel/types": "^7.7.4", - "esutils": "^2.0.0" - } - }, - "@babel/helper-call-delegate": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.7.4.tgz", - "integrity": "sha512-8JH9/B7J7tCYJ2PpWVpw9JhPuEVHztagNVuQAFBVFYluRMlpG7F1CgKEgGeL6KFqcsIa92ZYVj6DSc0XwmN1ZA==", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.7.4.tgz", - "integrity": "sha512-Mt+jBKaxL0zfOIWrfQpnfYCN7/rS6GKx6CCCfuoqVVd+17R8zNDlzVYmIi9qyb2wOk002NsmSTDymkIygDUH7A==", - "dev": true, - "requires": { - "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.6.0" - } - }, - "@babel/helper-define-map": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.7.4.tgz", - "integrity": "sha512-v5LorqOa0nVQUvAUTUF3KPastvUt/HzByXNamKQ6RdJRTV7j8rLL+WB5C/MzzWAwOomxDhYFb1wLLxHqox86lg==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.7.4", - "@babel/types": "^7.7.4", - "lodash": "^4.17.13" - } - }, - "@babel/helper-explode-assignable-expression": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.7.4.tgz", - "integrity": "sha512-2/SicuFrNSXsZNBxe5UGdLr+HZg+raWBLE9vC98bdYOKX/U6PY0mdGlYUJdtTDPSU0Lw0PNbKKDpwYHJLn2jLg==", - "dev": true, - "requires": { - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-function-name": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz", - "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.7.4", - "@babel/template": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz", - "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.7.4.tgz", - "integrity": "sha512-wQC4xyvc1Jo/FnLirL6CEgPgPCa8M74tOdjWpRhQYapz5JC7u3NYU1zCVoVAGCE3EaIP9T1A3iW0WLJ+reZlpQ==", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.7.4.tgz", - "integrity": "sha512-9KcA1X2E3OjXl/ykfMMInBK+uVdfIVakVe7W7Lg3wfXUNyS3Q1HWLFRwZIjhqiCGbslummPDnmb7vIekS0C1vw==", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-module-imports": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.7.4.tgz", - "integrity": "sha512-dGcrX6K9l8258WFjyDLJwuVKxR4XZfU0/vTUgOQYWEnRD8mgr+p4d6fCUMq/ys0h4CCt/S5JhbvtyErjWouAUQ==", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-module-transforms": { - "version": "7.7.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.7.5.tgz", - "integrity": "sha512-A7pSxyJf1gN5qXVcidwLWydjftUN878VkalhXX5iQDuGyiGK3sOrrKKHF4/A4fwHtnsotv/NipwAeLzY4KQPvw==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.7.4", - "@babel/helper-simple-access": "^7.7.4", - "@babel/helper-split-export-declaration": "^7.7.4", - "@babel/template": "^7.7.4", - "@babel/types": "^7.7.4", - "lodash": "^4.17.13" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.7.4.tgz", - "integrity": "sha512-VB7gWZ2fDkSuqW6b1AKXkJWO5NyNI3bFL/kK79/30moK57blr6NbH8xcl2XcKCwOmJosftWunZqfO84IGq3ZZg==", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", - "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", - "dev": true - }, - "@babel/helper-regex": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.5.5.tgz", - "integrity": "sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw==", - "dev": true, - "requires": { - "lodash": "^4.17.13" - } - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.7.4.tgz", - "integrity": "sha512-Sk4xmtVdM9sA/jCI80f+KS+Md+ZHIpjuqmYPk1M7F/upHou5e4ReYmExAiu6PVe65BhJPZA2CY9x9k4BqE5klw==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.7.4", - "@babel/helper-wrap-function": "^7.7.4", - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-replace-supers": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.7.4.tgz", - "integrity": "sha512-pP0tfgg9hsZWo5ZboYGuBn/bbYT/hdLPVSS4NMmiRJdwWhP0IznPwN9AE1JwyGsjSPLC364I0Qh5p+EPkGPNpg==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.7.4", - "@babel/helper-optimise-call-expression": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-simple-access": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.7.4.tgz", - "integrity": "sha512-zK7THeEXfan7UlWsG2A6CI/L9jVnI5+xxKZOdej39Y0YtDYKx9raHk5F2EtK9K8DHRTihYwg20ADt9S36GR78A==", - "dev": true, - "requires": { - "@babel/template": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz", - "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-wrap-function": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.7.4.tgz", - "integrity": "sha512-VsfzZt6wmsocOaVU0OokwrIytHND55yvyT4BPB9AIIgwr8+x7617hetdJTsuGwygN5RC6mxA9EJztTjuwm2ofg==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.7.4", - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/helpers": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.7.4.tgz", - "integrity": "sha512-ak5NGZGJ6LV85Q1Zc9gn2n+ayXOizryhjSUBTdu5ih1tlVCJeuQENzc4ItyCVhINVXvIT/ZQ4mheGIsfBkpskg==", - "dev": true, - "requires": { - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/highlight": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", - "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.7.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.5.tgz", - "integrity": "sha512-KNlOe9+/nk4i29g0VXgl8PEXIRms5xKLJeuZ6UptN0fHv+jDiriG+y94X6qAgWTR0h3KaoM1wK5G5h7MHFRSig==", - "dev": true - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.7.4.tgz", - "integrity": "sha512-1ypyZvGRXriY/QP668+s8sFr2mqinhkRDMPSQLNghCQE+GAkFtp+wkHVvg2+Hdki8gwP+NFzJBJ/N1BfzCCDEw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-remap-async-to-generator": "^7.7.4", - "@babel/plugin-syntax-async-generators": "^7.7.4" - } - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.7.4.tgz", - "integrity": "sha512-StH+nGAdO6qDB1l8sZ5UBV8AC3F2VW2I8Vfld73TMKyptMU9DY5YsJAS8U81+vEtxcH3Y/La0wG0btDrhpnhjQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-dynamic-import": "^7.7.4" - } - }, - "@babel/plugin-proposal-json-strings": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.7.4.tgz", - "integrity": "sha512-wQvt3akcBTfLU/wYoqm/ws7YOAQKu8EVJEvHip/mzkNtjaclQoCCIqKXFP5/eyfnfbQCDV3OLRIK3mIVyXuZlw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-json-strings": "^7.7.4" - } - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.7.4.tgz", - "integrity": "sha512-rnpnZR3/iWKmiQyJ3LKJpSwLDcX/nSXhdLk4Aq/tXOApIvyu7qoabrige0ylsAJffaUC51WiBu209Q0U+86OWQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-object-rest-spread": "^7.7.4" - } - }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.7.4.tgz", - "integrity": "sha512-DyM7U2bnsQerCQ+sejcTNZh8KQEUuC3ufzdnVnSiUv/qoGJp2Z3hanKL18KDhsBT5Wj6a7CMT5mdyCNJsEaA9w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.7.4" - } - }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.7.4.tgz", - "integrity": "sha512-cHgqHgYvffluZk85dJ02vloErm3Y6xtH+2noOBOJ2kXOJH3aVCDnj5eR/lVNlTnYu4hndAPJD3rTFjW3qee0PA==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.7.4.tgz", - "integrity": "sha512-Li4+EjSpBgxcsmeEF8IFcfV/+yJGxHXDirDkEoyFjumuwbmfCVHUt0HuowD/iGM7OhIRyXJH9YXxqiH6N815+g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.7.4.tgz", - "integrity": "sha512-jHQW0vbRGvwQNgyVxwDh4yuXu4bH1f5/EICJLAhl1SblLs2CDhrsmCk+v5XLdE9wxtAFRyxx+P//Iw+a5L/tTg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-flow": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.7.4.tgz", - "integrity": "sha512-2AMAWl5PsmM5KPkB22cvOkUyWk6MjUaqhHNU5nSPUl/ns3j5qLfw2SuYP5RbVZ0tfLvePr4zUScbICtDP2CUNw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.7.4.tgz", - "integrity": "sha512-QpGupahTQW1mHRXddMG5srgpHWqRLwJnJZKXTigB9RPFCCGbDGCgBeM/iC82ICXp414WeYx/tD54w7M2qRqTMg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.7.4.tgz", - "integrity": "sha512-wuy6fiMe9y7HeZBWXYCGt2RGxZOj0BImZ9EyXJVnVGBKO/Br592rbR3rtIQn0eQhAk9vqaKP5n8tVqEFBQMfLg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.7.4.tgz", - "integrity": "sha512-mObR+r+KZq0XhRVS2BrBKBpr5jqrqzlPvS9C9vuOf5ilSwzloAl7RPWLrgKdWS6IreaVrjHxTjtyqFiOisaCwg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.7.4.tgz", - "integrity": "sha512-4ZSuzWgFxqHRE31Glu+fEr/MirNZOMYmD/0BhBWyLyOOQz/gTAl7QmWm2hX1QxEIXsr2vkdlwxIzTyiYRC4xcQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.7.4.tgz", - "integrity": "sha512-wdsOw0MvkL1UIgiQ/IFr3ETcfv1xb8RMM0H9wbiDyLaJFyiDg5oZvDLCXosIXmFeIlweML5iOBXAkqddkYNizg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.7.4.tgz", - "integrity": "sha512-zUXy3e8jBNPiffmqkHRNDdZM2r8DWhCB7HhcoyZjiK1TxYEluLHAvQuYnTT+ARqRpabWqy/NHkO6e3MsYB5YfA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.7.4.tgz", - "integrity": "sha512-zpUTZphp5nHokuy8yLlyafxCJ0rSlFoSHypTUWgpdwoDXWQcseaect7cJ8Ppk6nunOM6+5rPMkod4OYKPR5MUg==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-remap-async-to-generator": "^7.7.4" - } - }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.7.4.tgz", - "integrity": "sha512-kqtQzwtKcpPclHYjLK//3lH8OFsCDuDJBaFhVwf8kqdnF6MN4l618UDlcA7TfRs3FayrHj+svYnSX8MC9zmUyQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.7.4.tgz", - "integrity": "sha512-2VBe9u0G+fDt9B5OV5DQH4KBf5DoiNkwFKOz0TCvBWvdAN2rOykCTkrL+jTLxfCAm76l9Qo5OqL7HBOx2dWggg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "lodash": "^4.17.13" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.7.4.tgz", - "integrity": "sha512-sK1mjWat7K+buWRuImEzjNf68qrKcrddtpQo3swi9j7dUcG6y6R6+Di039QN2bD1dykeswlagupEmpOatFHHUg==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.7.4", - "@babel/helper-define-map": "^7.7.4", - "@babel/helper-function-name": "^7.7.4", - "@babel/helper-optimise-call-expression": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.7.4", - "@babel/helper-split-export-declaration": "^7.7.4", - "globals": "^11.1.0" - } - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.7.4.tgz", - "integrity": "sha512-bSNsOsZnlpLLyQew35rl4Fma3yKWqK3ImWMSC/Nc+6nGjC9s5NFWAer1YQ899/6s9HxO2zQC1WoFNfkOqRkqRQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.7.4.tgz", - "integrity": "sha512-4jFMXI1Cu2aXbcXXl8Lr6YubCn6Oc7k9lLsu8v61TZh+1jny2BWmdtvY9zSUlLdGUvcy9DMAWyZEOqjsbeg/wA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.7.4.tgz", - "integrity": "sha512-mk0cH1zyMa/XHeb6LOTXTbG7uIJ8Rrjlzu91pUx/KS3JpcgaTDwMS8kM+ar8SLOvlL2Lofi4CGBAjCo3a2x+lw==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.7.4.tgz", - "integrity": "sha512-g1y4/G6xGWMD85Tlft5XedGaZBCIVN+/P0bs6eabmcPP9egFleMAo65OOjlhcz1njpwagyY3t0nsQC9oTFegJA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.7.4.tgz", - "integrity": "sha512-MCqiLfCKm6KEA1dglf6Uqq1ElDIZwFuzz1WH5mTf8k2uQSxEJMbOIEh7IZv7uichr7PMfi5YVSrr1vz+ipp7AQ==", - "dev": true, - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-flow-strip-types": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.7.4.tgz", - "integrity": "sha512-w9dRNlHY5ElNimyMYy0oQowvQpwt/PRHI0QS98ZJCTZU2bvSnKXo5zEiD5u76FBPigTm8TkqzmnUTg16T7qbkA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-flow": "^7.7.4" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.7.4.tgz", - "integrity": "sha512-zZ1fD1B8keYtEcKF+M1TROfeHTKnijcVQm0yO/Yu1f7qoDoxEIc/+GX6Go430Bg84eM/xwPFp0+h4EbZg7epAA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.7.4.tgz", - "integrity": "sha512-E/x09TvjHNhsULs2IusN+aJNRV5zKwxu1cpirZyRPw+FyyIKEHPXTsadj48bVpc1R5Qq1B5ZkzumuFLytnbT6g==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-literals": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.7.4.tgz", - "integrity": "sha512-X2MSV7LfJFm4aZfxd0yLVFrEXAgPqYoDG53Br/tCKiKYfX0MjVjQeWPIhPHHsCqzwQANq+FLN786fF5rgLS+gw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.7.4.tgz", - "integrity": "sha512-9VMwMO7i69LHTesL0RdGy93JU6a+qOPuvB4F4d0kR0zyVjJRVJRaoaGjhtki6SzQUu8yen/vxPKN6CWnCUw6bA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-modules-amd": { - "version": "7.7.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.7.5.tgz", - "integrity": "sha512-CT57FG4A2ZUNU1v+HdvDSDrjNWBrtCmSH6YbbgN3Lrf0Di/q/lWRxZrE72p3+HCCz9UjfZOEBdphgC0nzOS6DQ==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.7.5", - "@babel/helper-plugin-utils": "^7.0.0", - "babel-plugin-dynamic-import-node": "^2.3.0" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.7.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.5.tgz", - "integrity": "sha512-9Cq4zTFExwFhQI6MT1aFxgqhIsMWQWDVwOgLzl7PTWJHsNaqFvklAU+Oz6AQLAS0dJKTwZSOCo20INwktxpi3Q==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.7.5", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-simple-access": "^7.7.4", - "babel-plugin-dynamic-import-node": "^2.3.0" - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.7.4.tgz", - "integrity": "sha512-y2c96hmcsUi6LrMqvmNDPBBiGCiQu0aYqpHatVVu6kD4mFEXKjyNxd/drc18XXAf9dv7UXjrZwBVmTTGaGP8iw==", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0", - "babel-plugin-dynamic-import-node": "^2.3.0" - } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.7.4.tgz", - "integrity": "sha512-u2B8TIi0qZI4j8q4C51ktfO7E3cQ0qnaXFI1/OXITordD40tt17g/sXqgNNCcMTcBFKrUPcGDx+TBJuZxLx7tw==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.7.4.tgz", - "integrity": "sha512-jBUkiqLKvUWpv9GLSuHUFYdmHg0ujC1JEYoZUfeOOfNydZXp1sXObgyPatpcwjWgsdBGsagWW0cdJpX/DO2jMw==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.7.4" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.7.4.tgz", - "integrity": "sha512-CnPRiNtOG1vRodnsyGX37bHQleHE14B9dnnlgSeEs3ek3fHN1A1SScglTCg1sfbe7sRQ2BUcpgpTpWSfMKz3gg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-object-super": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.7.4.tgz", - "integrity": "sha512-ho+dAEhC2aRnff2JCA0SAK7V2R62zJd/7dmtoe7MHcso4C2mS+vZjn1Pb1pCVZvJs1mgsvv5+7sT+m3Bysb6eg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.7.4" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.7.4.tgz", - "integrity": "sha512-VJwhVePWPa0DqE9vcfptaJSzNDKrWU/4FbYCjZERtmqEs05g3UMXnYMZoXja7JAJ7Y7sPZipwm/pGApZt7wHlw==", - "dev": true, - "requires": { - "@babel/helper-call-delegate": "^7.7.4", - "@babel/helper-get-function-arity": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-property-literals": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.7.4.tgz", - "integrity": "sha512-MatJhlC4iHsIskWYyawl53KuHrt+kALSADLQQ/HkhTjX954fkxIEh4q5slL4oRAnsm/eDoZ4q0CIZpcqBuxhJQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-react-jsx": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.7.4.tgz", - "integrity": "sha512-LixU4BS95ZTEAZdPaIuyg/k8FiiqN9laQ0dMHB4MlpydHY53uQdWCUrwjLr5o6ilS6fAgZey4Q14XBjl5tL6xw==", - "dev": true, - "requires": { - "@babel/helper-builder-react-jsx": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-jsx": "^7.7.4" - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.7.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.5.tgz", - "integrity": "sha512-/8I8tPvX2FkuEyWbjRCt4qTAgZK0DVy8QRguhA524UH48RfGJy94On2ri+dCuwOpcerPRl9O4ebQkRcVzIaGBw==", - "dev": true, - "requires": { - "regenerator-transform": "^0.14.0" - } - }, - "@babel/plugin-transform-reserved-words": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.7.4.tgz", - "integrity": "sha512-OrPiUB5s5XvkCO1lS7D8ZtHcswIC57j62acAnJZKqGGnHP+TIc/ljQSrgdX/QyOTdEK5COAhuc820Hi1q2UgLQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.7.4.tgz", - "integrity": "sha512-q+suddWRfIcnyG5YiDP58sT65AJDZSUhXQDZE3r04AuqD6d/XLaQPPXSBzP2zGerkgBivqtQm9XKGLuHqBID6Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-spread": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.7.4.tgz", - "integrity": "sha512-8OSs0FLe5/80cndziPlg4R0K6HcWSM0zyNhHhLsmw/Nc5MaA49cAsnoJ/t/YZf8qkG7fD+UjTRaApVDB526d7Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.7.4.tgz", - "integrity": "sha512-Ls2NASyL6qtVe1H1hXts9yuEeONV2TJZmplLONkMPUG158CtmnrzW5Q5teibM5UVOFjG0D3IC5mzXR6pPpUY7A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.0.0" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.7.4.tgz", - "integrity": "sha512-sA+KxLwF3QwGj5abMHkHgshp9+rRz+oY9uoRil4CyLtgEuE/88dpkeWgNk5qKVsJE9iSfly3nvHapdRiIS2wnQ==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.7.4.tgz", - "integrity": "sha512-KQPUQ/7mqe2m0B8VecdyaW5XcQYaePyl9R7IsKd+irzj6jvbhoGnRE+M0aNkyAzI07VfUQ9266L5xMARitV3wg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.7.4.tgz", - "integrity": "sha512-N77UUIV+WCvE+5yHw+oks3m18/umd7y392Zv7mYTpFqHtkpcc+QUz+gLJNTWVlWROIWeLqY0f3OjZxV5TcXnRw==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/preset-env": { - "version": "7.7.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.7.5.tgz", - "integrity": "sha512-wDPbiaZdGzsJuTWlpLHJxmwslwHGLZ8F5v69zX3oAWeTOFWdy4OJHoTKg26oAnFg052v+/LAPY5os9KB0LrOEA==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-async-generator-functions": "^7.7.4", - "@babel/plugin-proposal-dynamic-import": "^7.7.4", - "@babel/plugin-proposal-json-strings": "^7.7.4", - "@babel/plugin-proposal-object-rest-spread": "^7.7.4", - "@babel/plugin-proposal-optional-catch-binding": "^7.7.4", - "@babel/plugin-proposal-unicode-property-regex": "^7.7.4", - "@babel/plugin-syntax-async-generators": "^7.7.4", - "@babel/plugin-syntax-dynamic-import": "^7.7.4", - "@babel/plugin-syntax-json-strings": "^7.7.4", - "@babel/plugin-syntax-object-rest-spread": "^7.7.4", - "@babel/plugin-syntax-optional-catch-binding": "^7.7.4", - "@babel/plugin-syntax-top-level-await": "^7.7.4", - "@babel/plugin-transform-arrow-functions": "^7.7.4", - "@babel/plugin-transform-async-to-generator": "^7.7.4", - "@babel/plugin-transform-block-scoped-functions": "^7.7.4", - "@babel/plugin-transform-block-scoping": "^7.7.4", - "@babel/plugin-transform-classes": "^7.7.4", - "@babel/plugin-transform-computed-properties": "^7.7.4", - "@babel/plugin-transform-destructuring": "^7.7.4", - "@babel/plugin-transform-dotall-regex": "^7.7.4", - "@babel/plugin-transform-duplicate-keys": "^7.7.4", - "@babel/plugin-transform-exponentiation-operator": "^7.7.4", - "@babel/plugin-transform-for-of": "^7.7.4", - "@babel/plugin-transform-function-name": "^7.7.4", - "@babel/plugin-transform-literals": "^7.7.4", - "@babel/plugin-transform-member-expression-literals": "^7.7.4", - "@babel/plugin-transform-modules-amd": "^7.7.5", - "@babel/plugin-transform-modules-commonjs": "^7.7.5", - "@babel/plugin-transform-modules-systemjs": "^7.7.4", - "@babel/plugin-transform-modules-umd": "^7.7.4", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.7.4", - "@babel/plugin-transform-new-target": "^7.7.4", - "@babel/plugin-transform-object-super": "^7.7.4", - "@babel/plugin-transform-parameters": "^7.7.4", - "@babel/plugin-transform-property-literals": "^7.7.4", - "@babel/plugin-transform-regenerator": "^7.7.5", - "@babel/plugin-transform-reserved-words": "^7.7.4", - "@babel/plugin-transform-shorthand-properties": "^7.7.4", - "@babel/plugin-transform-spread": "^7.7.4", - "@babel/plugin-transform-sticky-regex": "^7.7.4", - "@babel/plugin-transform-template-literals": "^7.7.4", - "@babel/plugin-transform-typeof-symbol": "^7.7.4", - "@babel/plugin-transform-unicode-regex": "^7.7.4", - "@babel/types": "^7.7.4", - "browserslist": "^4.6.0", - "core-js-compat": "^3.4.7", - "invariant": "^2.2.2", - "js-levenshtein": "^1.1.3", - "semver": "^5.5.0" - } - }, - "@babel/runtime": { - "version": "7.7.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.5.tgz", - "integrity": "sha512-UXhClKWTL7/vlYX49kETXti6VbpPJK/pdsIOqUMhUUES/lqThpNTsmC/0aU/IW4uozDUx17axjeqel7SCYF6EQ==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.2" - } - }, - "@babel/template": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz", - "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/traverse": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz", - "integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.4", - "@babel/helper-function-name": "^7.7.4", - "@babel/helper-split-export-declaration": "^7.7.4", - "@babel/parser": "^7.7.4", - "@babel/types": "^7.7.4", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz", - "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "@iarna/toml": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.3.tgz", - "integrity": "sha512-FmuxfCuolpLl0AnQ2NHSzoUKWEJDFl63qXjzdoWBVyFCXzMGm1spBzk7LeHNoVCiWCF7mRVms9e6jEV9+MoPbg==", - "dev": true - }, - "@mrmlnc/readdir-enhanced": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", - "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", - "dev": true, - "requires": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" - } - }, - "@nodelib/fs.stat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", - "dev": true - }, - "@parcel/fs": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@parcel/fs/-/fs-1.11.0.tgz", - "integrity": "sha512-86RyEqULbbVoeo8OLcv+LQ1Vq2PKBAvWTU9fCgALxuCTbbs5Ppcvll4Vr+Ko1AnmMzja/k++SzNAwJfeQXVlpA==", - "dev": true, - "requires": { - "@parcel/utils": "^1.11.0", - "mkdirp": "^0.5.1", - "rimraf": "^2.6.2" - } - }, - "@parcel/logger": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@parcel/logger/-/logger-1.11.1.tgz", - "integrity": "sha512-9NF3M6UVeP2udOBDILuoEHd8VrF4vQqoWHEafymO1pfSoOMfxrSJZw1MfyAAIUN/IFp9qjcpDCUbDZB+ioVevA==", - "dev": true, - "requires": { - "@parcel/workers": "^1.11.0", - "chalk": "^2.1.0", - "grapheme-breaker": "^0.3.2", - "ora": "^2.1.0", - "strip-ansi": "^4.0.0" - } - }, - "@parcel/utils": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@parcel/utils/-/utils-1.11.0.tgz", - "integrity": "sha512-cA3p4jTlaMeOtAKR/6AadanOPvKeg8VwgnHhOyfi0yClD0TZS/hi9xu12w4EzA/8NtHu0g6o4RDfcNjqN8l1AQ==", - "dev": true - }, - "@parcel/watcher": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-1.12.1.tgz", - "integrity": "sha512-od+uCtCxC/KoNQAIE1vWx1YTyKYY+7CTrxBJPRh3cDWw/C0tCtlBMVlrbplscGoEpt6B27KhJDCv82PBxOERNA==", - "dev": true, - "requires": { - "@parcel/utils": "^1.11.0", - "chokidar": "^2.1.5" - } - }, - "@parcel/workers": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@parcel/workers/-/workers-1.11.0.tgz", - "integrity": "sha512-USSjRAAQYsZFlv43FUPdD+jEGML5/8oLF0rUzPQTtK4q9kvaXr49F5ZplyLz5lox78cLZ0TxN2bIDQ1xhOkulQ==", - "dev": true, - "requires": { - "@parcel/utils": "^1.11.0", - "physical-cpu-count": "^2.0.0" - } - }, - "@types/node": { - "version": "13.9.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.1.tgz", - "integrity": "sha512-E6M6N0blf/jiZx8Q3nb0vNaswQeEyn0XlupO+xN6DtJ6r6IT4nXrTry7zhIfYvFCl3/8Cu6WIysmUBKiqV0bqQ==" - }, - "@types/prop-types": { - "version": "15.7.3", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", - "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" - }, - "@types/q": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz", - "integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==", - "dev": true - }, - "@types/react": { - "version": "16.9.23", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.23.tgz", - "integrity": "sha512-SsGVT4E7L2wLN3tPYLiF20hmZTPGuzaayVunfgXzUn1x4uHVsKH6QDJQ/TdpHqwsTLd4CwrmQ2vOgxN7gE24gw==", - "requires": { - "@types/prop-types": "*", - "csstype": "^2.2.0" - } - }, - "@types/react-dom": { - "version": "16.9.5", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.5.tgz", - "integrity": "sha512-BX6RQ8s9D+2/gDhxrj8OW+YD4R+8hj7FEM/OJHGNR0KipE1h1mSsf39YeyC81qafkq+N3rU3h3RFbLSwE5VqUg==", - "requires": { - "@types/react": "*" - } - }, - "@types/zen-observable": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.0.tgz", - "integrity": "sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg==" - }, - "@wry/context": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.4.4.tgz", - "integrity": "sha512-LrKVLove/zw6h2Md/KZyWxIkFM6AoyKp71OqpH9Hiip1csjPVoD3tPxlbQUNxEnHENks3UGgNpSBCAfq9KWuag==", - "requires": { - "@types/node": ">=6", - "tslib": "^1.9.3" - } - }, - "@wry/equality": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.1.9.tgz", - "integrity": "sha512-mB6ceGjpMGz1ZTza8HYnrPGos2mC6So4NhS1PtZ8s4Qt0K7fBiIGhpSxUbQmhwcSWE3no+bYxmI2OL6KuXYmoQ==", - "requires": { - "tslib": "^1.9.3" - } - }, - "abab": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", - "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==", - "dev": true - }, - "acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", - "dev": true - }, - "acorn-globals": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", - "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", - "dev": true, - "requires": { - "acorn": "^6.0.1", - "acorn-walk": "^6.0.1" - }, - "dependencies": { - "acorn": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", - "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", - "dev": true - } - } - }, - "acorn-walk": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", - "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", - "dev": true - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "alphanum-sort": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", - "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", - "dev": true - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "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" - } - }, - "ansi-to-html": { - "version": "0.6.13", - "resolved": "https://registry.npmjs.org/ansi-to-html/-/ansi-to-html-0.6.13.tgz", - "integrity": "sha512-Ys2/umuaTlQvP9DLkaa7UzRKF2FLrfod/hNHXS9QhXCrw7seObG6ksOGmNz3UoK+adwM8L9vQfG7mvaxfJ3Jvw==", - "dev": true, - "requires": { - "entities": "^1.1.2" - } - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": 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, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "apollo-boost": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/apollo-boost/-/apollo-boost-0.4.7.tgz", - "integrity": "sha512-jfc3aqO0vpCV+W662EOG5gq4AH94yIsvSgAUuDvS3o/Z+8Joqn4zGC9CgLCDHusK30mFgtsEgwEe0pZoedohsQ==", - "requires": { - "apollo-cache": "^1.3.4", - "apollo-cache-inmemory": "^1.6.5", - "apollo-client": "^2.6.7", - "apollo-link": "^1.0.6", - "apollo-link-error": "^1.0.3", - "apollo-link-http": "^1.3.1", - "graphql-tag": "^2.4.2", - "ts-invariant": "^0.4.0", - "tslib": "^1.10.0" - } - }, - "apollo-cache": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/apollo-cache/-/apollo-cache-1.3.4.tgz", - "integrity": "sha512-7X5aGbqaOWYG+SSkCzJNHTz2ZKDcyRwtmvW4mGVLRqdQs+HxfXS4dUS2CcwrAj449se6tZ6NLUMnjko4KMt3KA==", - "requires": { - "apollo-utilities": "^1.3.3", - "tslib": "^1.10.0" - } - }, - "apollo-cache-inmemory": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/apollo-cache-inmemory/-/apollo-cache-inmemory-1.6.5.tgz", - "integrity": "sha512-koB76JUDJaycfejHmrXBbWIN9pRKM0Z9CJGQcBzIOtmte1JhEBSuzsOUu7NQgiXKYI4iGoMREcnaWffsosZynA==", - "requires": { - "apollo-cache": "^1.3.4", - "apollo-utilities": "^1.3.3", - "optimism": "^0.10.0", - "ts-invariant": "^0.4.0", - "tslib": "^1.10.0" - } - }, - "apollo-client": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/apollo-client/-/apollo-client-2.6.8.tgz", - "integrity": "sha512-0zvJtAcONiozpa5z5zgou83iEKkBaXhhSSXJebFHRXs100SecDojyUWKjwTtBPn9HbM6o5xrvC5mo9VQ5fgAjw==", - "requires": { - "@types/zen-observable": "^0.8.0", - "apollo-cache": "1.3.4", - "apollo-link": "^1.0.0", - "apollo-utilities": "1.3.3", - "symbol-observable": "^1.0.2", - "ts-invariant": "^0.4.0", - "tslib": "^1.10.0", - "zen-observable": "^0.8.0" - } - }, - "apollo-link": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.13.tgz", - "integrity": "sha512-+iBMcYeevMm1JpYgwDEIDt/y0BB7VWyvlm/7x+TIPNLHCTCMgcEgDuW5kH86iQZWo0I7mNwQiTOz+/3ShPFmBw==", - "requires": { - "apollo-utilities": "^1.3.0", - "ts-invariant": "^0.4.0", - "tslib": "^1.9.3", - "zen-observable-ts": "^0.8.20" - } - }, - "apollo-link-error": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/apollo-link-error/-/apollo-link-error-1.1.12.tgz", - "integrity": "sha512-psNmHyuy3valGikt/XHJfe0pKJnRX19tLLs6P6EHRxg+6q6JMXNVLYPaQBkL0FkwdTCB0cbFJAGRYCBviG8TDA==", - "requires": { - "apollo-link": "^1.2.13", - "apollo-link-http-common": "^0.2.15", - "tslib": "^1.9.3" - } - }, - "apollo-link-http": { - "version": "1.5.16", - "resolved": "https://registry.npmjs.org/apollo-link-http/-/apollo-link-http-1.5.16.tgz", - "integrity": "sha512-IA3xA/OcrOzINRZEECI6IdhRp/Twom5X5L9jMehfzEo2AXdeRwAMlH5LuvTZHgKD8V1MBnXdM6YXawXkTDSmJw==", - "requires": { - "apollo-link": "^1.2.13", - "apollo-link-http-common": "^0.2.15", - "tslib": "^1.9.3" - } - }, - "apollo-link-http-common": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/apollo-link-http-common/-/apollo-link-http-common-0.2.15.tgz", - "integrity": "sha512-+Heey4S2IPsPyTf8Ag3PugUupASJMW894iVps6hXbvwtg1aHSNMXUYO5VG7iRHkPzqpuzT4HMBanCTXPjtGzxg==", - "requires": { - "apollo-link": "^1.2.13", - "ts-invariant": "^0.4.0", - "tslib": "^1.9.3" - } - }, - "apollo-utilities": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.3.3.tgz", - "integrity": "sha512-F14aX2R/fKNYMvhuP2t9GD9fggID7zp5I96MF5QeKYWDWTrkRdHRp4+SVfXUVN+cXOaB/IebfvRtzPf25CM0zw==", - "requires": { - "@wry/equality": "^0.1.2", - "fast-json-stable-stringify": "^2.0.0", - "ts-invariant": "^0.4.0", - "tslib": "^1.10.0" - } - }, - "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" - } - }, - "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 - }, - "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 - }, - "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 - }, - "array-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", - "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", - "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 - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "dev": true, - "requires": { - "object-assign": "^4.1.1", - "util": "0.10.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - } - } - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "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 - }, - "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 - }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "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 - }, - "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=", - "dev": true - }, - "aws4": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.0.tgz", - "integrity": "sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A==", - "dev": true - }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", - "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", - "dev": true, - "requires": { - "object.assign": "^4.1.0" - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - } - } - }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - }, - "dependencies": { - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true - } - } - }, - "babylon-walk": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/babylon-walk/-/babylon-walk-1.0.2.tgz", - "integrity": "sha1-OxWl3btIKni0zpwByLoYFwLZ1s4=", - "dev": true, - "requires": { - "babel-runtime": "^6.11.6", - "babel-types": "^6.15.0", - "lodash.clone": "^4.5.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": 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, - "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, - "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, - "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, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": 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=", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": 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==", - "dev": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", - "dev": true - }, - "brace-expansion": { - "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==", - "dev": 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, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "brfs": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/brfs/-/brfs-1.6.1.tgz", - "integrity": "sha512-OfZpABRQQf+Xsmju8XE9bDjs+uU4vLREGolP7bDgcpsI17QREyZ4Bl+2KLxxx1kCgA0fAIhKQBaBYh+PEcCqYQ==", - "dev": true, - "requires": { - "quote-stream": "^1.0.1", - "resolve": "^1.1.5", - "static-module": "^2.2.0", - "through2": "^2.0.0" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-process-hrtime": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", - "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", - "dev": true, - "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - }, - "dependencies": { - "pako": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", - "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", - "dev": true - } - } - }, - "browserslist": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.2.tgz", - "integrity": "sha512-+M4oeaTplPm/f1pXDw84YohEv7B1i/2Aisei8s4s6k3QsoSHa7i5sz8u/cGQkkatCPxMASKxPualR4wwYgVboA==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001015", - "electron-to-chromium": "^1.3.322", - "node-releases": "^1.1.42" - } - }, - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "buffer-equal": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", - "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=", - "dev": true - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "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, - "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" - } - }, - "call-me-maybe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", - "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", - "dev": true - }, - "caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", - "dev": true, - "requires": { - "callsites": "^2.0.0" - } - }, - "caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", - "dev": true, - "requires": { - "caller-callsite": "^2.0.0" - } - }, - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "caniuse-lite": { - "version": "1.0.30001015", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001015.tgz", - "integrity": "sha512-/xL2AbW/XWHNu1gnIrO8UitBGoFthcsDgU9VLK1/dpsoxbaD5LscHozKze05R6WLsBvLhqv78dAPozMFQBYLbQ==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "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" - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "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" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "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==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "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, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-spinners": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.3.1.tgz", - "integrity": "sha512-1QL4544moEsDVH9T/l6Cemov/37iv1RtoKf7NJ04A60+4MREXNfx/QvavbH6QoGdsD4N4Mwy49cmaINR/o2mdg==", - "dev": true - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.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 - }, - "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" - } - } - } - }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", - "dev": true - }, - "coa": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", - "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", - "dev": true, - "requires": { - "@types/q": "^1.5.1", - "chalk": "^2.4.1", - "q": "^1.1.2" - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", - "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", - "dev": true, - "requires": { - "color-convert": "^1.9.1", - "color-string": "^1.5.2" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "color-string": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", - "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", - "dev": true, - "requires": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "command-exists": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.8.tgz", - "integrity": "sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw==", - "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 - }, - "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 - }, - "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 - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.10", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz", - "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==", - "dev": true - }, - "core-js-compat": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.4.7.tgz", - "integrity": "sha512-57+mgz/P/xsGdjwQYkwtBZR3LuISaxD1dEwVDtbk8xJMqAmwqaxLOvnNT7kdJ7jYE/NjNptyzXi+IQFMi/2fCw==", - "dev": true, - "requires": { - "browserslist": "^4.8.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "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=", - "dev": true - }, - "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dev": true, - "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "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, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "css-color-names": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", - "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", - "dev": true - }, - "css-declaration-sorter": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", - "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", - "dev": true, - "requires": { - "postcss": "^7.0.1", - "timsort": "^0.3.0" - } - }, - "css-modules-loader-core": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/css-modules-loader-core/-/css-modules-loader-core-1.1.0.tgz", - "integrity": "sha1-WQhmgpShvs0mGuCkziGwtVHyHRY=", - "dev": true, - "requires": { - "icss-replace-symbols": "1.1.0", - "postcss": "6.0.1", - "postcss-modules-extract-imports": "1.1.0", - "postcss-modules-local-by-default": "1.2.0", - "postcss-modules-scope": "1.1.0", - "postcss-modules-values": "1.3.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "dependencies": { - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "postcss": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.1.tgz", - "integrity": "sha1-AA29H47vIXqjaLmiEsX8QLKo8/I=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "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=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "css-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", - "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", - "dev": true, - "requires": { - "boolbase": "^1.0.0", - "css-what": "^3.2.1", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" - } - }, - "css-select-base-adapter": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", - "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", - "dev": true - }, - "css-selector-tokenizer": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz", - "integrity": "sha512-xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA==", - "dev": true, - "requires": { - "cssesc": "^0.1.0", - "fastparse": "^1.1.1", - "regexpu-core": "^1.0.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - }, - "regexpu-core": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", - "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", - "dev": true, - "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" - } - }, - "regjsgen": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", - "dev": true - }, - "regjsparser": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - } - } - } - }, - "css-tree": { - "version": "1.0.0-alpha.37", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", - "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", - "dev": true, - "requires": { - "mdn-data": "2.0.4", - "source-map": "^0.6.1" - } - }, - "css-unit-converter": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.1.tgz", - "integrity": "sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=", - "dev": true - }, - "css-what": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.2.1.tgz", - "integrity": "sha512-WwOrosiQTvyms+Ti5ZC5vGEK0Vod3FTt1ca+payZqvKuGJF+dq7bG63DstxtN0dpm6FxY27a/zS3Wten+gEtGw==", - "dev": true - }, - "cssesc": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz", - "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=", - "dev": true - }, - "cssnano": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz", - "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==", - "dev": true, - "requires": { - "cosmiconfig": "^5.0.0", - "cssnano-preset-default": "^4.0.7", - "is-resolvable": "^1.0.0", - "postcss": "^7.0.0" - } - }, - "cssnano-preset-default": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz", - "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==", - "dev": true, - "requires": { - "css-declaration-sorter": "^4.0.1", - "cssnano-util-raw-cache": "^4.0.1", - "postcss": "^7.0.0", - "postcss-calc": "^7.0.1", - "postcss-colormin": "^4.0.3", - "postcss-convert-values": "^4.0.1", - "postcss-discard-comments": "^4.0.2", - "postcss-discard-duplicates": "^4.0.2", - "postcss-discard-empty": "^4.0.1", - "postcss-discard-overridden": "^4.0.1", - "postcss-merge-longhand": "^4.0.11", - "postcss-merge-rules": "^4.0.3", - "postcss-minify-font-values": "^4.0.2", - "postcss-minify-gradients": "^4.0.2", - "postcss-minify-params": "^4.0.2", - "postcss-minify-selectors": "^4.0.2", - "postcss-normalize-charset": "^4.0.1", - "postcss-normalize-display-values": "^4.0.2", - "postcss-normalize-positions": "^4.0.2", - "postcss-normalize-repeat-style": "^4.0.2", - "postcss-normalize-string": "^4.0.2", - "postcss-normalize-timing-functions": "^4.0.2", - "postcss-normalize-unicode": "^4.0.1", - "postcss-normalize-url": "^4.0.1", - "postcss-normalize-whitespace": "^4.0.2", - "postcss-ordered-values": "^4.1.2", - "postcss-reduce-initial": "^4.0.3", - "postcss-reduce-transforms": "^4.0.2", - "postcss-svgo": "^4.0.2", - "postcss-unique-selectors": "^4.0.1" - } - }, - "cssnano-util-get-arguments": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", - "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=", - "dev": true - }, - "cssnano-util-get-match": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", - "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=", - "dev": true - }, - "cssnano-util-raw-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", - "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "cssnano-util-same-parent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", - "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", - "dev": true - }, - "csso": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.2.tgz", - "integrity": "sha512-kS7/oeNVXkHWxby5tHVxlhjizRCSv8QdU7hB2FpdAibDU8FjTAolhNjKNTiLzXtUrKT6HwClE81yXwEk1309wg==", - "dev": true, - "requires": { - "css-tree": "1.0.0-alpha.37" - } - }, - "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - }, - "cssstyle": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", - "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", - "dev": true, - "requires": { - "cssom": "0.3.x" - } - }, - "csstype": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.9.tgz", - "integrity": "sha512-xz39Sb4+OaTsULgUERcCk+TJj8ylkL4aSVDQiX/ksxbELSqwkgt4d4RD7fovIdgJGSuNYqwZEiVjYY5l0ask+Q==" - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "data-urls": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", - "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", - "dev": true, - "requires": { - "abab": "^2.0.0", - "whatwg-mimetype": "^2.2.0", - "whatwg-url": "^7.0.0" - } - }, - "deasync": { - "version": "0.1.16", - "resolved": "https://registry.npmjs.org/deasync/-/deasync-0.1.16.tgz", - "integrity": "sha512-FNCjDwxGbhK+Ye8fmE3p2ahIjERhkbuwX+WVGZPtSbAh9LfE1Saa2p0l+f0t11sIlk9D8W+Bym+cDp6r5yghAQ==", - "dev": true, - "requires": { - "bindings": "^1.5.0", - "node-addon-api": "^1.7.1" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "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 - }, - "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 - }, - "defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", - "dev": true, - "requires": { - "clone": "^1.0.2" - }, - "dependencies": { - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "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, - "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, - "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, - "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, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==", - "dev": true - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==", - "dev": true - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true - }, - "domexception": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", - "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", - "dev": true, - "requires": { - "webidl-conversions": "^4.0.2" - } - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "dev": true, - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "dev": true, - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "dot-prop": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", - "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", - "dev": true, - "requires": { - "is-obj": "^1.0.0" - } - }, - "dotenv": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-5.0.1.tgz", - "integrity": "sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow==", - "dev": true - }, - "dotenv-expand": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", - "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", - "dev": true - }, - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", - "dev": true, - "requires": { - "readable-stream": "^2.0.2" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.322", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.322.tgz", - "integrity": "sha512-Tc8JQEfGQ1MzfSzI/bTlSr7btJv/FFO7Yh6tanqVmIWOuNCu6/D1MilIEgLtmWqIrsv+o4IjpLAhgMBr/ncNAA==", - "dev": true - }, - "elliptic": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", - "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "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 - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - }, - "envinfo": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.5.0.tgz", - "integrity": "sha512-jDgnJaF/Btomk+m3PZDTTCb5XIIIX3zYItnCRfF73zVgvinLoRomuhi75Y4su0PtQxWz4v66XnLLckyvyJTOIQ==", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.16.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.3.tgz", - "integrity": "sha512-WtY7Fx5LiOnSYgF5eg/1T+GONaGmpvpPdCpSnYij+U2gDTL0UPfWrhDw7b2IYb+9NQJsYpCA0wOQvZfsd6YwRw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "string.prototype.trimleft": "^2.1.0", - "string.prototype.trimright": "^2.1.0" - }, - "dependencies": { - "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", - "dev": true - } - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "escodegen": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.1.tgz", - "integrity": "sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q==", - "dev": true, - "requires": { - "esprima": "^3.1.3", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - } - }, - "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", - "dev": true - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true - }, - "events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", - "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "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, - "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, - "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, - "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, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": 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, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": 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, - "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, - "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, - "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, - "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, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "falafel": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/falafel/-/falafel-2.2.4.tgz", - "integrity": "sha512-0HXjo8XASWRmsS0X1EkhwEMZaD3Qvp7FfURwjLKjG1ghfRm/MGZl2r4cWUTv41KdNghTw4OUMmVtdGQp3+H+uQ==", - "dev": true, - "requires": { - "acorn": "^7.1.1", - "foreach": "^2.0.5", - "isarray": "^2.0.1", - "object-keys": "^1.0.6" - }, - "dependencies": { - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - } - } - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, - "fast-glob": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", - "dev": true, - "requires": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" - } - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "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 - }, - "fastparse": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", - "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", - "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 - }, - "filesize": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz", - "integrity": "sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==", - "dev": true - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": 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, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "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==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "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, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "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 - }, - "get-port": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "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" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": 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, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "glob-to-regexp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", - "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 - }, - "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", - "dev": true - }, - "grapheme-breaker": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/grapheme-breaker/-/grapheme-breaker-0.3.2.tgz", - "integrity": "sha1-W55reMODJFLSuiuxy4MPlidkEKw=", - "dev": true, - "requires": { - "brfs": "^1.2.0", - "unicode-trie": "^0.3.1" - } - }, - "graphql": { - "version": "14.6.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.6.0.tgz", - "integrity": "sha512-VKzfvHEKybTKjQVpTFrA5yUq2S9ihcZvfJAtsDBBCuV6wauPu1xl/f9ehgVf0FcEJJs4vz6ysb/ZMkGigQZseg==", - "requires": { - "iterall": "^1.2.2" - } - }, - "graphql-tag": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.10.3.tgz", - "integrity": "sha512-4FOv3ZKfA4WdOKJeHdz6B3F/vxBLSgmBcGeAFPf4n1F64ltJUvOOerNj0rsJxONQGdhUMynQIvd6LzB+1J5oKA==" - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "dev": true, - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - } - } - }, - "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-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "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, - "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, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hex-color-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", - "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", - "dev": true - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "hoist-non-react-statics": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", - "integrity": "sha512-wbg3bpgA/ZqWrZuMOeJi8+SKMhr7X9TesL/rXMjTzh0p0JUBo3II8DHboYbuIXWRlttrUFxwcu/5kygrCw8fJw==", - "requires": { - "react-is": "^16.7.0" - } - }, - "hsl-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", - "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=", - "dev": true - }, - "hsla-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", - "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=", - "dev": true - }, - "html-comment-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", - "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==", - "dev": true - }, - "html-encoding-sniffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", - "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", - "dev": true, - "requires": { - "whatwg-encoding": "^1.0.1" - } - }, - "html-tags": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-1.2.0.tgz", - "integrity": "sha1-x43mW1Zjqll5id0rerSSANfk25g=", - "dev": true - }, - "htmlnano": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/htmlnano/-/htmlnano-0.2.5.tgz", - "integrity": "sha512-X1iPSwXG/iF9bVs+/obt2n6F64uH0ETkA8zp7qFDmLW9/+A6ueHGeb/+qD67T21qUY22owZPMdawljN50ajkqA==", - "dev": true, - "requires": { - "cssnano": "^4.1.10", - "normalize-html-whitespace": "^1.0.0", - "posthtml": "^0.12.0", - "posthtml-render": "^1.1.5", - "purgecss": "^1.4.0", - "svgo": "^1.3.2", - "terser": "^4.3.9", - "uncss": "^0.17.2" - }, - "dependencies": { - "posthtml": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.12.0.tgz", - "integrity": "sha512-aNUEP/SfKUXAt+ghG51LC5MmafChBZeslVe/SSdfKIgLGUVRE68mrMF4V8XbH07ZifM91tCSuxY3eHIFLlecQw==", - "dev": true, - "requires": { - "posthtml-parser": "^0.4.1", - "posthtml-render": "^1.1.5" - } - }, - "terser": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.4.2.tgz", - "integrity": "sha512-Uufrsvhj9O1ikwgITGsZ5EZS6qPokUOkCegS7fYOdGTv+OA90vndUbU6PEjr5ePqHfNUbGyMO7xyIZv2MhsALQ==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - } - } - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "http-errors": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", - "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "icss-replace-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", - "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", - "dev": true - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "dev": true, - "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - } - }, - "indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "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" - } - }, - "is-absolute-url": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", - "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", - "dev": true - }, - "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, - "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, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "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=", - "dev": true, - "requires": { - "binary-extensions": "^1.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 - }, - "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", - "dev": true - }, - "is-color-stop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", - "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", - "dev": true, - "requires": { - "css-color-names": "^0.0.4", - "hex-color-regex": "^1.1.0", - "hsl-regex": "^1.0.0", - "hsla-regex": "^1.0.0", - "rgb-regex": "^1.0.1", - "rgba-regex": "^1.0.0" - } - }, - "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=", - "dev": 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, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": 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 - } - } - }, - "is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", - "dev": true - }, - "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 - }, - "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 - }, - "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 - }, - "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, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-html": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-html/-/is-html-1.1.0.tgz", - "integrity": "sha1-4E8cGNOUhRETlvmgJz6rUa8hhGQ=", - "dev": true, - "requires": { - "html-tags": "^1.0.0" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": 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, - "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=", - "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, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, - "requires": { - "has": "^1.0.1" - } - }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, - "is-svg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", - "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==", - "dev": true, - "requires": { - "html-comment-regex": "^1.1.0" - } - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "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 - }, - "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 - }, - "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=", - "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 - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "iterall": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz", - "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==" - }, - "js-levenshtein": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", - "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "dependencies": { - "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 - } - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, - "jsdom": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-14.1.0.tgz", - "integrity": "sha512-O901mfJSuTdwU2w3Sn+74T+RnDVP+FuV5fH8tcPWyqrseRAb0s5xOtPgCFiPOtLcyK7CLIJwPyD83ZqQWvA5ng==", - "dev": true, - "requires": { - "abab": "^2.0.0", - "acorn": "^6.0.4", - "acorn-globals": "^4.3.0", - "array-equal": "^1.0.0", - "cssom": "^0.3.4", - "cssstyle": "^1.1.1", - "data-urls": "^1.1.0", - "domexception": "^1.0.1", - "escodegen": "^1.11.0", - "html-encoding-sniffer": "^1.0.2", - "nwsapi": "^2.1.3", - "parse5": "5.1.0", - "pn": "^1.1.0", - "request": "^2.88.0", - "request-promise-native": "^1.0.5", - "saxes": "^3.1.9", - "symbol-tree": "^3.2.2", - "tough-cookie": "^2.5.0", - "w3c-hr-time": "^1.0.1", - "w3c-xmlserializer": "^1.1.2", - "webidl-conversions": "^4.0.2", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^7.0.0", - "ws": "^6.1.2", - "xml-name-validator": "^3.0.0" - }, - "dependencies": { - "acorn": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", - "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", - "dev": true - }, - "escodegen": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.12.0.tgz", - "integrity": "sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg==", - "dev": true, - "requires": { - "esprima": "^3.1.3", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - } - }, - "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } - } - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "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 - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "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==", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "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 - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "lodash.clone": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", - "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=", - "dev": true - }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", - "dev": true - }, - "lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", - "dev": true - }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", - "dev": true - }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "requires": { - "chalk": "^2.0.1" - } - }, - "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==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "magic-string": { - "version": "0.22.5", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz", - "integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==", - "dev": true, - "requires": { - "vlq": "^0.2.2" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "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, - "requires": { - "object-visit": "^1.0.0" - } - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "mdn-data": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", - "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", - "dev": true - }, - "merge-source-map": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.0.4.tgz", - "integrity": "sha1-pd5GU42uhNQRTMXqArR3KmNGcB8=", - "dev": true, - "requires": { - "source-map": "^0.5.6" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "merge2": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", - "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": 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" - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "mime-db": { - "version": "1.42.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", - "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==", - "dev": true - }, - "mime-types": { - "version": "2.1.25", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", - "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", - "dev": true, - "requires": { - "mime-db": "1.42.0" - } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "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, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "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==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "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, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "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 - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": 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" - } - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node-addon-api": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.1.tgz", - "integrity": "sha512-2+DuKodWvwRTrCfKOeR24KIc5unKjOh8mz17NCzVnHWfjAdDqbfbjqh7gUT+BkXBRQM52+xCHciKWonJ3CbJMQ==", - "dev": true - }, - "node-forge": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.6.tgz", - "integrity": "sha512-sol30LUpz1jQFBjOKwbjxijiE3b6pjd74YwfD0fJOKPjF+fONKb2Yg8rYgS6+bK6VDl+/wfr4IYpC7jDzLUIfw==", - "dev": true - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } - } - }, - "node-releases": { - "version": "1.1.42", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.42.tgz", - "integrity": "sha512-OQ/ESmUqGawI2PRX+XIRao44qWYBBfN54ImQYdWVTQqUckuejOg76ysSqDBK8NG3zwySRVnX36JwDQ6x+9GxzA==", - "dev": true, - "requires": { - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "normalize-html-whitespace": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/normalize-html-whitespace/-/normalize-html-whitespace-1.0.0.tgz", - "integrity": "sha512-9ui7CGtOOlehQu0t/OhhlmDyc71mKVlv+4vF+me4iZLPrNtRL2xoquEdfZxasC/bdQi/Hr3iTrpyRKIG+ocabA==", - "dev": true - }, - "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 - }, - "normalize-url": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", - "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", - "dev": true - }, - "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, - "requires": { - "boolbase": "~1.0.0" - } - }, - "nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", - "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==", - "dev": true - }, - "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, - "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, - "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, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-inspect": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.4.1.tgz", - "integrity": "sha512-wqdhLpfCUbEsoEwl3FXwGyv8ief1k/1aUdIPCqVnupM6e8l63BEJdiF/0swtn04/8p05tG/T0FrpTlfwvljOdw==", - "dev": true - }, - "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-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", - "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.1" - } - }, - "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, - "requires": { - "isobject": "^3.0.1" - } - }, - "object.values": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", - "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.12.0", - "function-bind": "^1.1.1", - "has": "^1.0.3" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "opn": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", - "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", - "dev": true, - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimism": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.10.3.tgz", - "integrity": "sha512-9A5pqGoQk49H6Vhjb9kPgAeeECfUDF6aIICbMDL23kDLStBn1MWk3YvcZ4xWF9CsSf6XEgvRLkXy4xof/56vVw==", - "requires": { - "@wry/context": "^0.4.0" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "ora": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-2.1.0.tgz", - "integrity": "sha512-hNNlAd3gfv/iPmsNxYoAPLvxg7HuPozww7fFonMZvL84tP6Ox5igfk5j/+a9rtJJwqMgKK+JgWsAQik5o0HTLA==", - "dev": true, - "requires": { - "chalk": "^2.3.1", - "cli-cursor": "^2.1.0", - "cli-spinners": "^1.1.0", - "log-symbols": "^2.2.0", - "strip-ansi": "^4.0.0", - "wcwidth": "^1.0.1" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", - "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", - "dev": true - }, - "parcel-bundler": { - "version": "1.12.4", - "resolved": "https://registry.npmjs.org/parcel-bundler/-/parcel-bundler-1.12.4.tgz", - "integrity": "sha512-G+iZGGiPEXcRzw0fiRxWYCKxdt/F7l9a0xkiU4XbcVRJCSlBnioWEwJMutOCCpoQmaQtjB4RBHDGIHN85AIhLQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/core": "^7.4.4", - "@babel/generator": "^7.4.4", - "@babel/parser": "^7.4.4", - "@babel/plugin-transform-flow-strip-types": "^7.4.4", - "@babel/plugin-transform-modules-commonjs": "^7.4.4", - "@babel/plugin-transform-react-jsx": "^7.0.0", - "@babel/preset-env": "^7.4.4", - "@babel/runtime": "^7.4.4", - "@babel/template": "^7.4.4", - "@babel/traverse": "^7.4.4", - "@babel/types": "^7.4.4", - "@iarna/toml": "^2.2.0", - "@parcel/fs": "^1.11.0", - "@parcel/logger": "^1.11.1", - "@parcel/utils": "^1.11.0", - "@parcel/watcher": "^1.12.1", - "@parcel/workers": "^1.11.0", - "ansi-to-html": "^0.6.4", - "babylon-walk": "^1.0.2", - "browserslist": "^4.1.0", - "chalk": "^2.1.0", - "clone": "^2.1.1", - "command-exists": "^1.2.6", - "commander": "^2.11.0", - "core-js": "^2.6.5", - "cross-spawn": "^6.0.4", - "css-modules-loader-core": "^1.1.0", - "cssnano": "^4.0.0", - "deasync": "^0.1.14", - "dotenv": "^5.0.0", - "dotenv-expand": "^5.1.0", - "envinfo": "^7.3.1", - "fast-glob": "^2.2.2", - "filesize": "^3.6.0", - "get-port": "^3.2.0", - "htmlnano": "^0.2.2", - "is-glob": "^4.0.0", - "is-url": "^1.2.2", - "js-yaml": "^3.10.0", - "json5": "^1.0.1", - "micromatch": "^3.0.4", - "mkdirp": "^0.5.1", - "node-forge": "^0.7.1", - "node-libs-browser": "^2.0.0", - "opn": "^5.1.0", - "postcss": "^7.0.11", - "postcss-value-parser": "^3.3.1", - "posthtml": "^0.11.2", - "posthtml-parser": "^0.4.0", - "posthtml-render": "^1.1.3", - "resolve": "^1.4.0", - "semver": "^5.4.1", - "serialize-to-js": "^3.0.0", - "serve-static": "^1.12.4", - "source-map": "0.6.1", - "terser": "^3.7.3", - "v8-compile-cache": "^2.0.0", - "ws": "^5.1.1" - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "parse5": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", - "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", - "dev": true - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": 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 - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "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 - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, - "physical-cpu-count": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/physical-cpu-count/-/physical-cpu-count-2.0.0.tgz", - "integrity": "sha1-GN4vl+S/epVRrXURlCtUlverpmA=", - "dev": true - }, - "pn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", - "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", - "dev": true - }, - "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 - }, - "postcss": { - "version": "7.0.24", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.24.tgz", - "integrity": "sha512-Xl0XvdNWg+CblAXzNvbSOUvgJXwSjmbAKORqyw9V2AlHrm1js2gFw9y3jibBAhpKZi8b5JzJCVh/FyzPsTtgTA==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "postcss-calc": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.1.tgz", - "integrity": "sha512-oXqx0m6tb4N3JGdmeMSc/i91KppbYsFZKdH0xMOqK8V1rJlzrKlTdokz8ozUXLVejydRN6u2IddxpcijRj2FqQ==", - "dev": true, - "requires": { - "css-unit-converter": "^1.1.1", - "postcss": "^7.0.5", - "postcss-selector-parser": "^5.0.0-rc.4", - "postcss-value-parser": "^3.3.1" - } - }, - "postcss-colormin": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", - "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "color": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-convert-values": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", - "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", - "dev": true, - "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-discard-comments": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", - "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-discard-duplicates": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", - "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-discard-empty": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", - "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-discard-overridden": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", - "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-merge-longhand": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", - "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", - "dev": true, - "requires": { - "css-color-names": "0.0.4", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "stylehacks": "^4.0.0" - } - }, - "postcss-merge-rules": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", - "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "caniuse-api": "^3.0.0", - "cssnano-util-same-parent": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0", - "vendors": "^1.0.0" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", - "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", - "dev": true, - "requires": { - "dot-prop": "^4.1.1", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } - } - }, - "postcss-minify-font-values": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", - "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", - "dev": true, - "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-minify-gradients": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", - "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", - "dev": true, - "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "is-color-stop": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-minify-params": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", - "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", - "dev": true, - "requires": { - "alphanum-sort": "^1.0.0", - "browserslist": "^4.0.0", - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "uniqs": "^2.0.0" - } - }, - "postcss-minify-selectors": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", - "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", - "dev": true, - "requires": { - "alphanum-sort": "^1.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", - "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", - "dev": true, - "requires": { - "dot-prop": "^4.1.1", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } - } - }, - "postcss-modules-extract-imports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz", - "integrity": "sha1-thTJcgvmgW6u41+zpfqh26agXds=", - "dev": true, - "requires": { - "postcss": "^6.0.1" - }, - "dependencies": { - "postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" - } - } - } - }, - "postcss-modules-local-by-default": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz", - "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=", - "dev": true, - "requires": { - "css-selector-tokenizer": "^0.7.0", - "postcss": "^6.0.1" - }, - "dependencies": { - "postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" - } - } - } - }, - "postcss-modules-scope": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz", - "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=", - "dev": true, - "requires": { - "css-selector-tokenizer": "^0.7.0", - "postcss": "^6.0.1" - }, - "dependencies": { - "postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" - } - } - } - }, - "postcss-modules-values": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz", - "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=", - "dev": true, - "requires": { - "icss-replace-symbols": "^1.1.0", - "postcss": "^6.0.1" - }, - "dependencies": { - "postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" - } - } - } - }, - "postcss-normalize-charset": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", - "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-normalize-display-values": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", - "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", - "dev": true, - "requires": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-normalize-positions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", - "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", - "dev": true, - "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-normalize-repeat-style": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", - "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", - "dev": true, - "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-normalize-string": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", - "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", - "dev": true, - "requires": { - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-normalize-timing-functions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", - "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", - "dev": true, - "requires": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-normalize-unicode": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", - "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-normalize-url": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", - "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", - "dev": true, - "requires": { - "is-absolute-url": "^2.0.0", - "normalize-url": "^3.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-normalize-whitespace": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", - "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", - "dev": true, - "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-ordered-values": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", - "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", - "dev": true, - "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-reduce-initial": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", - "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "caniuse-api": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0" - } - }, - "postcss-reduce-transforms": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", - "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", - "dev": true, - "requires": { - "cssnano-util-get-match": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "dev": true, - "requires": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - }, - "dependencies": { - "cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", - "dev": true - } - } - }, - "postcss-svgo": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz", - "integrity": "sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==", - "dev": true, - "requires": { - "is-svg": "^3.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "svgo": "^1.0.0" - } - }, - "postcss-unique-selectors": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", - "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", - "dev": true, - "requires": { - "alphanum-sort": "^1.0.0", - "postcss": "^7.0.0", - "uniqs": "^2.0.0" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "posthtml": { - "version": "0.11.6", - "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.11.6.tgz", - "integrity": "sha512-C2hrAPzmRdpuL3iH0TDdQ6XCc9M7Dcc3zEW5BLerY65G4tWWszwv6nG/ksi6ul5i2mx22ubdljgktXCtNkydkw==", - "dev": true, - "requires": { - "posthtml-parser": "^0.4.1", - "posthtml-render": "^1.1.5" - } - }, - "posthtml-parser": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.4.2.tgz", - "integrity": "sha512-BUIorsYJTvS9UhXxPTzupIztOMVNPa/HtAm9KHni9z6qEfiJ1bpOBL5DfUOL9XAc3XkLIEzBzpph+Zbm4AdRAg==", - "dev": true, - "requires": { - "htmlparser2": "^3.9.2" - } - }, - "posthtml-render": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-1.1.5.tgz", - "integrity": "sha512-yvt54j0zCBHQVEFAuR+yHld8CZrCa/E1Z/OcFNCV1IEWTLVxT8O7nYnM4IIw1CD4r8kaRd3lc42+0lgCKgm87w==", - "dev": true - }, - "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 - }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, - "psl": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.6.0.tgz", - "integrity": "sha512-SYKKmVel98NCOYXpkwUqZqh0ahZeeKfmisiLIcEZdsb+WbLv02g/dI5BUmZnIyOe7RzZtLax81nnb2HbvC2tzA==", - "dev": true - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "purgecss": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/purgecss/-/purgecss-1.4.1.tgz", - "integrity": "sha512-5jONV/D/3nfa+lC425+LA+OWe5/LDn4a79cac+TnzJq3VczwnWlpIDdW275hHsGhkzIlqATQsYFLW7or0cSwNQ==", - "dev": true, - "requires": { - "glob": "^7.1.3", - "postcss": "^7.0.14", - "postcss-selector-parser": "^6.0.0", - "yargs": "^14.0.0" - }, - "dependencies": { - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true - }, - "postcss-selector-parser": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", - "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==", - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } - } - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", - "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==", - "dev": true - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "quote-stream": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/quote-stream/-/quote-stream-1.0.2.tgz", - "integrity": "sha1-hJY/jJwmuULhU/7rU6rnRlK34LI=", - "dev": true, - "requires": { - "buffer-equal": "0.0.1", - "minimist": "^1.1.3", - "through2": "^2.0.0" - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "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==", - "dev": true - }, - "react": { - "version": "16.13.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.13.0.tgz", - "integrity": "sha512-TSavZz2iSLkq5/oiE7gnFzmURKZMltmi193rm5HEoUDAXpzT9Kzw6oNZnGoai/4+fUnm7FqS5dwgUL34TujcWQ==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2" - } - }, - "react-apollo": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/react-apollo/-/react-apollo-3.1.3.tgz", - "integrity": "sha512-orCZNoAkgveaK5b75y7fw1MSqSHOU/Wuu9rRFOGmRQBSQVZjvV4DI+hj604rHmuN9+WDABxb5W48wTa0F/xNZQ==", - "requires": { - "@apollo/react-common": "^3.1.3", - "@apollo/react-components": "^3.1.3", - "@apollo/react-hoc": "^3.1.3", - "@apollo/react-hooks": "^3.1.3", - "@apollo/react-ssr": "^3.1.3" - } - }, - "react-dom": { - "version": "16.13.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.0.tgz", - "integrity": "sha512-y09d2c4cG220DzdlFkPTnVvGTszVvNpC73v+AaLGLHbkpy3SSgvYq8x0rNwPJ/Rk/CicTNgk0hbHNw1gMEZAXg==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.19.0" - } - }, - "react-is": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", - "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==" - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "regenerate": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", - "dev": true - }, - "regenerate-unicode-properties": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz", - "integrity": "sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==", - "dev": true, - "requires": { - "regenerate": "^1.4.0" - } - }, - "regenerator-runtime": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", - "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", - "dev": true - }, - "regenerator-transform": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.1.tgz", - "integrity": "sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ==", - "dev": true, - "requires": { - "private": "^0.1.6" - } - }, - "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, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "regexpu-core": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.6.0.tgz", - "integrity": "sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==", - "dev": true, - "requires": { - "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.1.0", - "regjsgen": "^0.5.0", - "regjsparser": "^0.6.0", - "unicode-match-property-ecmascript": "^1.0.4", - "unicode-match-property-value-ecmascript": "^1.1.0" - } - }, - "regjsgen": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz", - "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==", - "dev": true - }, - "regjsparser": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", - "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - } - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": 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 - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "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==", - "dev": true, - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - } - } - } - }, - "request-promise-core": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", - "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", - "dev": true, - "requires": { - "lodash": "^4.17.15" - } - }, - "request-promise-native": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", - "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", - "dev": true, - "requires": { - "request-promise-core": "1.1.3", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - } - }, - "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 - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "resolve": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.13.1.tgz", - "integrity": "sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true - }, - "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 - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "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 - }, - "rgb-regex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", - "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=", - "dev": true - }, - "rgba-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", - "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true - }, - "saxes": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", - "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", - "dev": true, - "requires": { - "xmlchars": "^2.1.1" - } - }, - "scheduler": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.0.tgz", - "integrity": "sha512-xowbVaTPe9r7y7RUejcK73/j8tt2jfiyTednOvHbA8JoClvMYCp+r8QegLwK/n8zWQAtZb1fFnER4XLBZXrCxA==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.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, - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - } - } - }, - "serialize-to-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/serialize-to-js/-/serialize-to-js-3.0.1.tgz", - "integrity": "sha512-TokHD6rY0yQxMmZCjeL8Oj+XuQK6uEx8JnBjt7PuqwWa2qY79Wb/KyhEDduTUC8Gl3S7c40jefWve7f5t4L8Lw==", - "dev": true - }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "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, - "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, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shallow-copy": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/shallow-copy/-/shallow-copy-0.0.1.tgz", - "integrity": "sha1-QV9CcC1z2BAzApLMXuhurhoRoXA=", - "dev": true - }, - "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, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "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 - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "dev": true, - "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==", - "dev": true - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": 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" - }, - "dependencies": { - "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" - } - }, - "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, - "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, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "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, - "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, - "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, - "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, - "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, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "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, - "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, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "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 - }, - "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "dev": true, - "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", - "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "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, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "requires": { - "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" - } - }, - "stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "dev": true - }, - "static-eval": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.3.tgz", - "integrity": "sha512-zsxDGucfAh8T339sSKgpFbvg15Fms2IVaJGC+jqp0bVsxhcpM+iMeAI8weNo8dmf4OblgifTBUoyk1vGVtYw2w==", - "dev": true, - "requires": { - "escodegen": "^1.11.1" - }, - "dependencies": { - "escodegen": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.12.0.tgz", - "integrity": "sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg==", - "dev": true, - "requires": { - "esprima": "^3.1.3", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - } - } - } - }, - "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, - "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, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "static-module": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/static-module/-/static-module-2.2.5.tgz", - "integrity": "sha512-D8vv82E/Kpmz3TXHKG8PPsCPg+RAX6cbCOyvjM6x04qZtQ47EtJFVwRsdov3n5d6/6ynrOY9XB4JkaZwB2xoRQ==", - "dev": true, - "requires": { - "concat-stream": "~1.6.0", - "convert-source-map": "^1.5.1", - "duplexer2": "~0.1.4", - "escodegen": "~1.9.0", - "falafel": "^2.1.0", - "has": "^1.0.1", - "magic-string": "^0.22.4", - "merge-source-map": "1.0.4", - "object-inspect": "~1.4.0", - "quote-stream": "~1.0.2", - "readable-stream": "~2.3.3", - "shallow-copy": "~0.0.1", - "static-eval": "^2.0.0", - "through2": "~2.0.3" - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - }, - "stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", - "dev": true - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - } - }, - "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" - }, - "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 - }, - "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" - } - } - } - }, - "string.prototype.trimleft": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", - "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - } - }, - "string.prototype.trimright": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", - "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "stylehacks": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", - "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", - "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", - "dev": true, - "requires": { - "dot-prop": "^4.1.1", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "svgo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", - "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "coa": "^2.0.2", - "css-select": "^2.0.0", - "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.37", - "csso": "^4.0.2", - "js-yaml": "^3.13.1", - "mkdirp": "~0.5.1", - "object.values": "^1.1.0", - "sax": "~1.2.4", - "stable": "^0.1.8", - "unquote": "~1.1.1", - "util.promisify": "~1.0.0" - } - }, - "symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" - }, - "symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true - }, - "terser": { - "version": "3.17.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz", - "integrity": "sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ==", - "dev": true, - "requires": { - "commander": "^2.19.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.10" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "timsort": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", - "dev": true - }, - "tiny-inflate": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", - "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", - "dev": true - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "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, - "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, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "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, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "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=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "dev": true - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "ts-invariant": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.4.4.tgz", - "integrity": "sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==", - "requires": { - "tslib": "^1.9.3" - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "uncss": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/uncss/-/uncss-0.17.2.tgz", - "integrity": "sha512-hu2HquwDItuGDem4YsJROdAD8SknmWtM24zwhQax6J1se8tPjV1cnwPKhtjodzBaUhaL8Zb3hlGdZ2WAUpbAOg==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "glob": "^7.1.4", - "is-absolute-url": "^3.0.1", - "is-html": "^1.1.0", - "jsdom": "^14.1.0", - "lodash": "^4.17.15", - "postcss": "^7.0.17", - "postcss-selector-parser": "6.0.2", - "request": "^2.88.0" - }, - "dependencies": { - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true - }, - "is-absolute-url": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", - "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", - "dev": true - }, - "postcss-selector-parser": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", - "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==", - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } - } - }, - "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==", - "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==", - "dev": true, - "requires": { - "unicode-canonical-property-names-ecmascript": "^1.0.4", - "unicode-property-aliases-ecmascript": "^1.0.4" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz", - "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==", - "dev": true - }, - "unicode-property-aliases-ecmascript": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", - "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==", - "dev": true - }, - "unicode-trie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-0.3.1.tgz", - "integrity": "sha1-1nHd3YkQGgi6w3tqUWEBBgIFIIU=", - "dev": true, - "requires": { - "pako": "^0.2.5", - "tiny-inflate": "^1.0.0" - } - }, - "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, - "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=", - "dev": true - }, - "uniqs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", - "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", - "dev": true - }, - "unquote": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", - "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=", - "dev": true - }, - "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, - "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, - "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, - "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 - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "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 - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "util.promisify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", - "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "object.getownpropertydescriptors": "^2.0.3" - } - }, - "uuid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", - "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", - "dev": true - }, - "v8-compile-cache": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", - "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", - "dev": true - }, - "vendors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.3.tgz", - "integrity": "sha512-fOi47nsJP5Wqefa43kyWSg80qF+Q3XA6MUkgi7Hp1HQaKDQW4cQrK2D0P7mmbFtsV1N89am55Yru/nyEwRubcw==", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vlq": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", - "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", - "dev": true - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "w3c-hr-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", - "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", - "dev": true, - "requires": { - "browser-process-hrtime": "^0.1.2" - } - }, - "w3c-xmlserializer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", - "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", - "dev": true, - "requires": { - "domexception": "^1.0.1", - "webidl-conversions": "^4.0.2", - "xml-name-validator": "^3.0.0" - } - }, - "wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", - "dev": true, - "requires": { - "defaults": "^1.0.3" - } - }, - "webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", - "dev": true - }, - "whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "requires": { - "iconv-lite": "0.4.24" - } - }, - "whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true - }, - "whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "dev": true, - "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - }, - "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" - } - }, - "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 - }, - "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 - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.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 - }, - "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" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "ws": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", - "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } - }, - "xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true - }, - "xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yargs": { - "version": "14.2.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.2.tgz", - "integrity": "sha512-/4ld+4VV5RnrynMhPZJ/ZpOCGSCeghMykZ3BhdFBDa9Wy/RH6uEGNWDJog+aUlq+9OM1CFTgtYRW5Is1Po9NOA==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.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": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^15.0.0" - } - }, - "yargs-parser": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.0.tgz", - "integrity": "sha512-xLTUnCMc4JhxrPEPUYD5IBR1mWCK/aT6+RJ/K29JY2y1vD+FhtgKK0AXRWvI262q3QSffAQuTouFIKUuHX89wQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "zen-observable": { - "version": "0.8.15", - "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz", - "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==" - }, - "zen-observable-ts": { - "version": "0.8.20", - "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.8.20.tgz", - "integrity": "sha512-2rkjiPALhOtRaDX6pWyNqK1fnP5KkJJybYebopNSn6wDG1lxBoFs2+nwwXKoA6glHIrtwrfBBy6da0stkKtTAA==", - "requires": { - "tslib": "^1.9.3", - "zen-observable": "^0.8.0" - } - } - } -} diff --git a/examples/apollo-client/package.json b/examples/apollo-client/package.json deleted file mode 100644 index 99a2a7f5a..000000000 --- a/examples/apollo-client/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "private": true, - "scripts": { - "start": "parcel ./src/index.html" - }, - "dependencies": { - "@types/react": "^16.9.23", - "@types/react-dom": "^16.9.5", - "apollo-boost": "^0.4.7", - "graphql": "^14.6.0", - "react": "^16.13.0", - "react-apollo": "^3.1.3", - "react-dom": "^16.13.0" - }, - "devDependencies": { - "parcel-bundler": "^1.12.4" - }, - "alias": { - "util": "./mocks/utils.js", - "glob": "./mocks/empty-module.js", - "fs": "./mocks/empty-module.js", - "path": "./mocks/empty-module.js" - }, - "browserslist": [ - "last 1 Chrome version" - ] -} diff --git a/examples/apollo-client/src/App.tsx b/examples/apollo-client/src/App.tsx deleted file mode 100644 index 4b39158e1..000000000 --- a/examples/apollo-client/src/App.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import React, { FC } from "react"; -import { ApolloProvider } from "react-apollo"; -import ApolloClient from "apollo-boost"; - -import Counter from "./Counter/Counter"; - -const App: FC<{ client: ApolloClient }> = ({ client }) => ( - - - -); - -export default App; diff --git a/examples/apollo-client/src/Counter/Counter.tsx b/examples/apollo-client/src/Counter/Counter.tsx deleted file mode 100644 index 0783d32fb..000000000 --- a/examples/apollo-client/src/Counter/Counter.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React, { FC } from "react"; -import { useQuery } from "react-apollo"; -import { gql } from "apollo-boost"; - -import IncrementButton from "./IncrementButton"; -import DecrementButton from "./DecrementButton"; -import CounterType from "./counter.type"; - -const Counter: FC = () => { - const { data, loading } = useQuery<{ counter: CounterType }>(gql` - query { - counter @client { - value - } - } - `); - - return ( - <> -

Counter:

-

{loading ? "Loading..." : data!.counter.value}

- - - - ); -}; - -export default Counter; diff --git a/examples/apollo-client/src/Counter/DecrementButton.tsx b/examples/apollo-client/src/Counter/DecrementButton.tsx deleted file mode 100644 index 6edfb3917..000000000 --- a/examples/apollo-client/src/Counter/DecrementButton.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import React, { FC } from "react"; -import { useMutation } from "react-apollo"; -import { gql } from "apollo-boost"; - -const DecrementButton: FC = () => { - const [decrement] = useMutation<() => void>(gql` - mutation { - decrementCounter @client - } - `); - - return ; -}; - -export default DecrementButton; diff --git a/examples/apollo-client/src/Counter/IncrementButton.tsx b/examples/apollo-client/src/Counter/IncrementButton.tsx deleted file mode 100644 index 87ff77d18..000000000 --- a/examples/apollo-client/src/Counter/IncrementButton.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import React, { FC } from "react"; -import { useMutation } from "react-apollo"; -import { gql } from "apollo-boost"; - -const IncrementButton: FC = () => { - const [increment] = useMutation<() => void>(gql` - mutation { - incrementCounter @client - } - `); - - return ; -}; - -export default IncrementButton; diff --git a/examples/apollo-client/src/Counter/counter.resolver.ts b/examples/apollo-client/src/Counter/counter.resolver.ts deleted file mode 100644 index d5ee39c62..000000000 --- a/examples/apollo-client/src/Counter/counter.resolver.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { gql } from "apollo-boost"; -import { ApolloCache } from "apollo-cache"; -import { Resolver, Mutation, Ctx } from "../../../../src"; - -import ApolloContext from "../apollo/context"; -import CounterType from "./counter.type"; - -@Resolver(of => CounterType) -export default class CounterResolver { - @Mutation(returns => Boolean, { nullable: true }) - incrementCounter(@Ctx() { cache }: ApolloContext) { - this.updateCounter(cache, value => value + 1); - } - - @Mutation(returns => Boolean, { nullable: true }) - decrementCounter(@Ctx() { cache }: ApolloContext) { - this.updateCounter(cache, value => Math.max(value - 1, 0)); - } - - private updateCounter(cache: ApolloCache, getNewValueCb: (value: number) => number) { - const query = gql` - query { - counter @client { - __typename - value - } - } - `; - const { counter } = cache.readQuery<{ counter: CounterType }>({ query })!; - const data = { - counter: { - ...counter, - value: getNewValueCb(counter.value), - }, - }; - cache.writeQuery({ query, data }); - } -} diff --git a/examples/apollo-client/src/Counter/counter.type.ts b/examples/apollo-client/src/Counter/counter.type.ts deleted file mode 100644 index ef4e292ee..000000000 --- a/examples/apollo-client/src/Counter/counter.type.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { ObjectType, Field } from "../../../../src"; - -@ObjectType() -export default class Counter { - @Field() - value!: number; -} diff --git a/examples/apollo-client/src/apollo/client.ts b/examples/apollo-client/src/apollo/client.ts deleted file mode 100644 index c20e45ee8..000000000 --- a/examples/apollo-client/src/apollo/client.ts +++ /dev/null @@ -1,27 +0,0 @@ -import ApolloClient, { Resolvers } from "apollo-boost"; -import { buildTypeDefsAndResolvers } from "../../../../src"; - -import CounterResolver from "../Counter/counter.resolver"; -import CounterType from "../Counter/counter.type"; - -export default async function createApolloClient() { - const { typeDefs, resolvers } = await buildTypeDefsAndResolvers({ - resolvers: [CounterResolver], - skipCheck: true, // allow for schema without queries - }); - - const client = new ApolloClient({ - clientState: { - typeDefs, - resolvers: resolvers as Resolvers, - defaults: { - counter: { - __typename: CounterType.name, - value: 0, - }, - }, - }, - }); - - return client; -} diff --git a/examples/apollo-client/src/apollo/context.ts b/examples/apollo-client/src/apollo/context.ts deleted file mode 100644 index 17b5db616..000000000 --- a/examples/apollo-client/src/apollo/context.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { ApolloCache } from "apollo-cache"; - -export default interface ApolloContext { - cache: ApolloCache; -} diff --git a/examples/apollo-client/src/index.html b/examples/apollo-client/src/index.html deleted file mode 100644 index f5dc3e95d..000000000 --- a/examples/apollo-client/src/index.html +++ /dev/null @@ -1,6 +0,0 @@ - - -
- - - diff --git a/examples/apollo-client/src/index.tsx b/examples/apollo-client/src/index.tsx deleted file mode 100644 index b4428f3e0..000000000 --- a/examples/apollo-client/src/index.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import "reflect-metadata"; -import React from "react"; -import ReactDOM from "react-dom"; - -import App from "./App"; -import createApolloClient from "./apollo/client"; - -async function bootstrap() { - const client = await createApolloClient(); - ReactDOM.render(, document.getElementById("root")!); -} - -bootstrap(); diff --git a/examples/apollo-client/tsconfig.json b/examples/apollo-client/tsconfig.json deleted file mode 100644 index 504f8b919..000000000 --- a/examples/apollo-client/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "compilerOptions": { - "target": "es2017", - "module": "esnext", - "moduleResolution": "node", - "strict": true, - "lib": ["es2017", "dom"], - "esModuleInterop": true, - "jsx": "react", - "experimentalDecorators": true, - "emitDecoratorMetadata": true - } -} diff --git a/examples/apollo-federation-2/accounts/data.ts b/examples/apollo-federation-2/accounts/data.ts new file mode 100644 index 000000000..fde6e39b3 --- /dev/null +++ b/examples/apollo-federation-2/accounts/data.ts @@ -0,0 +1,20 @@ +import { User } from "./user"; + +function createUser(userData: Partial) { + return Object.assign(new User(), userData); +} + +export const users: User[] = [ + createUser({ + id: "1", + name: "Ada Lovelace", + birthDate: "1815-12-10", + username: "@ada", + }), + createUser({ + id: "2", + name: "Alan Turing", + birthDate: "1912-06-23", + username: "@complete", + }), +]; diff --git a/examples/apollo-federation-2/accounts/index.ts b/examples/apollo-federation-2/accounts/index.ts new file mode 100644 index 000000000..ca29e999a --- /dev/null +++ b/examples/apollo-federation-2/accounts/index.ts @@ -0,0 +1,25 @@ +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { AccountsResolver } from "./resolver"; +import { User } from "./user"; +import { resolveUserReference } from "./user.reference"; +import { buildFederatedSchema } from "../helpers/buildFederatedSchema"; + +export async function listen(port: number): Promise { + const schema = await buildFederatedSchema( + { + resolvers: [AccountsResolver], + orphanedTypes: [User], + }, + { + User: { __resolveReference: resolveUserReference }, + }, + ); + + const server = new ApolloServer({ schema }); + + const { url } = await startStandaloneServer(server, { listen: { port } }); + console.log(`Accounts service ready at ${url}`); + + return url; +} diff --git a/examples/apollo-federation-2/accounts/resolver.ts b/examples/apollo-federation-2/accounts/resolver.ts new file mode 100644 index 000000000..1f92764f5 --- /dev/null +++ b/examples/apollo-federation-2/accounts/resolver.ts @@ -0,0 +1,11 @@ +import { Query, Resolver } from "type-graphql"; +import { users } from "./data"; +import { User } from "./user"; + +@Resolver(_of => User) +export class AccountsResolver { + @Query(_returns => User) + me(): User { + return users[0]; + } +} diff --git a/examples/apollo-federation/accounts/user-reference.ts b/examples/apollo-federation-2/accounts/user.reference.ts similarity index 82% rename from examples/apollo-federation/accounts/user-reference.ts rename to examples/apollo-federation-2/accounts/user.reference.ts index aed680677..3d7112253 100644 --- a/examples/apollo-federation/accounts/user-reference.ts +++ b/examples/apollo-federation-2/accounts/user.reference.ts @@ -1,5 +1,5 @@ import { users } from "./data"; -import User from "./user"; +import { type User } from "./user"; export async function resolveUserReference(reference: Pick): Promise { return users.find(u => u.id === reference.id)!; diff --git a/examples/apollo-federation-2/accounts/user.ts b/examples/apollo-federation-2/accounts/user.ts new file mode 100644 index 000000000..ea9e6c423 --- /dev/null +++ b/examples/apollo-federation-2/accounts/user.ts @@ -0,0 +1,18 @@ +import { Directive, Field, ID, ObjectType } from "type-graphql"; + +@Directive(`@key(fields: "id")`) +@ObjectType() +export class User { + @Field(_type => ID) + id!: string; + + @Directive("@shareable") + @Field() + username!: string; + + @Field() + name!: string; + + @Field() + birthDate!: string; +} diff --git a/examples/apollo-federation-2/examples.graphql b/examples/apollo-federation-2/examples.graphql new file mode 100644 index 000000000..c1c39f816 --- /dev/null +++ b/examples/apollo-federation-2/examples.graphql @@ -0,0 +1,23 @@ +query { + topProducts { + __typename + name + price + shippingEstimate + inStock + reviews { + body + author { + name + birthDate + reviews { + product { + __typename + name + } + body + } + } + } + } +} diff --git a/examples/apollo-federation-2/helpers/buildFederatedSchema.ts b/examples/apollo-federation-2/helpers/buildFederatedSchema.ts new file mode 100644 index 000000000..a303dfb33 --- /dev/null +++ b/examples/apollo-federation-2/helpers/buildFederatedSchema.ts @@ -0,0 +1,40 @@ +import { buildSubgraphSchema } from "@apollo/subgraph"; +import { type IResolvers, printSchemaWithDirectives } from "@graphql-tools/utils"; +import gql from "graphql-tag"; +import deepMerge from "lodash.merge"; +import { type BuildSchemaOptions, buildSchema, createResolversMap } from "type-graphql"; + +export async function buildFederatedSchema( + options: Omit, + referenceResolvers?: IResolvers, +) { + // build TypeGraphQL schema + const schema = await buildSchema({ + ...options, + skipCheck: true, // disable check to allow schemas without query, etc. + }); + + // build Apollo Subgraph schema + const federatedSchema = buildSubgraphSchema({ + typeDefs: gql` + extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.3" + import: [ + "@key" + "@shareable" + "@provides" + "@extends" + "@requires" + "@external" + "@interfaceObject" + ] + ) + ${printSchemaWithDirectives(schema)} + `, + // merge schema's resolvers with reference resolvers + resolvers: deepMerge(createResolversMap(schema) as any, referenceResolvers), + }); + + return federatedSchema; +} diff --git a/examples/apollo-federation-2/index.ts b/examples/apollo-federation-2/index.ts new file mode 100644 index 000000000..e13b587c3 --- /dev/null +++ b/examples/apollo-federation-2/index.ts @@ -0,0 +1,46 @@ +import "reflect-metadata"; +import path from "path"; +import { ApolloGateway, IntrospectAndCompose } from "@apollo/gateway"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { emitSchemaDefinitionFile } from "type-graphql"; +import * as accounts from "./accounts"; +import * as inventory from "./inventory"; +import * as products from "./products"; +import * as reviews from "./reviews"; + +const startGraph = async (name: string, urlOrPromise: string | Promise) => { + const url = await urlOrPromise; + return { name, url }; +}; + +async function bootstrap() { + const subgraphs = await Promise.all([ + startGraph("accounts", accounts.listen(4001)), + startGraph("reviews", reviews.listen(4002)), + startGraph("products", products.listen(4003)), + startGraph("inventory", inventory.listen(4004)), + ]); + + const schemaGateway = new ApolloGateway({ + supergraphSdl: new IntrospectAndCompose({ + subgraphs, + }), + }); + const { schema } = await schemaGateway.load(); + await emitSchemaDefinitionFile(path.resolve(__dirname, "schema.graphql"), schema); + await schemaGateway.stop(); + + const gateway = new ApolloGateway({ + supergraphSdl: new IntrospectAndCompose({ + subgraphs, + }), + }); + const server = new ApolloServer({ gateway }); + + const { url } = await startStandaloneServer(server, { listen: { port: 4000 } }); + + console.log(`Apollo Gateway ready at ${url}`); +} + +bootstrap().catch(console.error); diff --git a/examples/apollo-federation-2/inventory/data.ts b/examples/apollo-federation-2/inventory/data.ts new file mode 100644 index 000000000..4796e02b2 --- /dev/null +++ b/examples/apollo-federation-2/inventory/data.ts @@ -0,0 +1,10 @@ +export interface Inventory { + upc: string; + inStock: boolean; +} + +export const inventory: Inventory[] = [ + { upc: "1", inStock: true }, + { upc: "2", inStock: false }, + { upc: "3", inStock: true }, +]; diff --git a/examples/apollo-federation-2/inventory/index.ts b/examples/apollo-federation-2/inventory/index.ts new file mode 100644 index 000000000..ad8cdfb1d --- /dev/null +++ b/examples/apollo-federation-2/inventory/index.ts @@ -0,0 +1,25 @@ +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { Product } from "./product"; +import { resolveProductReference } from "./product.reference"; +import { InventoryResolver } from "./resolver"; +import { buildFederatedSchema } from "../helpers/buildFederatedSchema"; + +export async function listen(port: number): Promise { + const schema = await buildFederatedSchema( + { + resolvers: [InventoryResolver], + orphanedTypes: [Product], + }, + { + Product: { __resolveReference: resolveProductReference }, + }, + ); + + const server = new ApolloServer({ schema }); + + const { url } = await startStandaloneServer(server, { listen: { port } }); + console.log(`Inventory service ready at ${url}`); + + return url; +} diff --git a/examples/apollo-federation/inventory/product-reference.ts b/examples/apollo-federation-2/inventory/product.reference.ts similarity index 84% rename from examples/apollo-federation/inventory/product-reference.ts rename to examples/apollo-federation-2/inventory/product.reference.ts index 7cc998250..31798d5f8 100644 --- a/examples/apollo-federation/inventory/product-reference.ts +++ b/examples/apollo-federation-2/inventory/product.reference.ts @@ -1,5 +1,5 @@ import { inventory } from "./data"; -import Product from "./product"; +import { Product } from "./product"; export async function resolveProductReference( reference: Pick, @@ -7,7 +7,7 @@ export async function resolveProductReference( const found = inventory.find(i => i.upc === reference.upc); if (!found) { - return; + return undefined; } return Object.assign(new Product(), { diff --git a/examples/apollo-federation-2/inventory/product.ts b/examples/apollo-federation-2/inventory/product.ts new file mode 100644 index 000000000..c581bb2ae --- /dev/null +++ b/examples/apollo-federation-2/inventory/product.ts @@ -0,0 +1,22 @@ +import { Directive, Field, ObjectType } from "type-graphql"; + +@ObjectType() +@Directive("@extends") +@Directive("@interfaceObject") +@Directive(`@key(fields: "upc")`) +export class Product { + @Field() + @Directive("@external") + upc!: string; + + @Field() + @Directive("@external") + weight!: number; + + @Field() + @Directive("@external") + price!: number; + + @Field() + inStock!: boolean; +} diff --git a/examples/apollo-federation-2/inventory/resolver.ts b/examples/apollo-federation-2/inventory/resolver.ts new file mode 100644 index 000000000..cf593d874 --- /dev/null +++ b/examples/apollo-federation-2/inventory/resolver.ts @@ -0,0 +1,17 @@ +import { Directive, FieldResolver, Resolver, Root } from "type-graphql"; +import { Product } from "./product"; + +@Resolver(_of => Product) +export class InventoryResolver { + @Directive(`@requires(fields: "price weight")`) + @FieldResolver(_returns => Number) + async shippingEstimate(@Root() product: Product): Promise { + // free for expensive items + if (product.price > 1000) { + return 0; + } + + // estimate is based on weight + return product.weight * 0.5; + } +} diff --git a/examples/apollo-federation-2/products/data.ts b/examples/apollo-federation-2/products/data.ts new file mode 100644 index 000000000..93de15818 --- /dev/null +++ b/examples/apollo-federation-2/products/data.ts @@ -0,0 +1,27 @@ +import { Dining } from "./dining"; +import { type Product } from "./product"; +import { Seating } from "./seating"; + +export const products: Product[] = [ + Object.assign(new Dining(), { + upc: "1", + name: "Table", + price: 899, + weight: 100, + height: "3ft", + }), + Object.assign(new Seating(), { + upc: "2", + name: "Couch", + price: 1299, + weight: 1000, + seats: 2, + }), + Object.assign(new Seating(), { + upc: "3", + name: "Chair", + price: 54, + weight: 50, + seats: 1, + }), +]; diff --git a/examples/apollo-federation-2/products/dining.ts b/examples/apollo-federation-2/products/dining.ts new file mode 100644 index 000000000..251781c49 --- /dev/null +++ b/examples/apollo-federation-2/products/dining.ts @@ -0,0 +1,9 @@ +import { Directive, Field, ObjectType } from "type-graphql"; +import { Product } from "./product"; + +@Directive(`@key(fields: "upc")`) +@ObjectType({ implements: Product }) +export class Dining extends Product { + @Field() + height!: string; +} diff --git a/examples/apollo-federation-2/products/index.ts b/examples/apollo-federation-2/products/index.ts new file mode 100644 index 000000000..b5c31911f --- /dev/null +++ b/examples/apollo-federation-2/products/index.ts @@ -0,0 +1,25 @@ +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { Product } from "./product"; +import { resolveProductReference } from "./product.reference"; +import { ProductsResolver } from "./resolver"; +import { buildFederatedSchema } from "../helpers/buildFederatedSchema"; + +export async function listen(port: number): Promise { + const schema = await buildFederatedSchema( + { + resolvers: [ProductsResolver], + orphanedTypes: [Product], + }, + { + Product: { __resolveReference: resolveProductReference }, + }, + ); + + const server = new ApolloServer({ schema }); + + const { url } = await startStandaloneServer(server, { listen: { port } }); + console.log(`Products service ready at ${url}`); + + return url; +} diff --git a/examples/apollo-federation/products/product-reference.ts b/examples/apollo-federation-2/products/product.reference.ts similarity index 83% rename from examples/apollo-federation/products/product-reference.ts rename to examples/apollo-federation-2/products/product.reference.ts index 1d9d9b53b..e6488b6c5 100644 --- a/examples/apollo-federation/products/product-reference.ts +++ b/examples/apollo-federation-2/products/product.reference.ts @@ -1,5 +1,5 @@ import { products } from "./data"; -import Product from "./product"; +import { type Product } from "./product"; export async function resolveProductReference( reference: Pick, diff --git a/examples/apollo-federation-2/products/product.ts b/examples/apollo-federation-2/products/product.ts new file mode 100644 index 000000000..bcdb56180 --- /dev/null +++ b/examples/apollo-federation-2/products/product.ts @@ -0,0 +1,17 @@ +import { Directive, Field, InterfaceType } from "type-graphql"; + +@Directive(`@key(fields: "upc")`) +@InterfaceType() +export abstract class Product { + @Field() + upc!: string; + + @Field() + name!: string; + + @Field() + price!: number; + + @Field() + weight!: number; +} diff --git a/examples/apollo-federation-2/products/resolver.ts b/examples/apollo-federation-2/products/resolver.ts new file mode 100644 index 000000000..047cf52cb --- /dev/null +++ b/examples/apollo-federation-2/products/resolver.ts @@ -0,0 +1,14 @@ +import { Arg, Query, Resolver } from "type-graphql"; +import { products } from "./data"; +import { Product } from "./product"; + +@Resolver(_of => Product) +export class ProductsResolver { + @Query(_returns => [Product]) + async topProducts( + @Arg("first", { defaultValue: 5 }) + first: number, + ): Promise { + return products.slice(0, first); + } +} diff --git a/examples/apollo-federation-2/products/seating.ts b/examples/apollo-federation-2/products/seating.ts new file mode 100644 index 000000000..8f76c4e58 --- /dev/null +++ b/examples/apollo-federation-2/products/seating.ts @@ -0,0 +1,9 @@ +import { Directive, Field, ObjectType } from "type-graphql"; +import { Product } from "./product"; + +@Directive(`@key(fields: "upc")`) +@ObjectType({ implements: Product }) +export class Seating extends Product { + @Field() + seats!: number; +} diff --git a/examples/apollo-federation-2/reviews/index.ts b/examples/apollo-federation-2/reviews/index.ts new file mode 100644 index 000000000..876531428 --- /dev/null +++ b/examples/apollo-federation-2/reviews/index.ts @@ -0,0 +1,23 @@ +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { Product } from "./product/product"; +import { ProductReviewsResolver } from "./product/resolver"; +import { ReviewsResolver } from "./review/resolver"; +import { Review } from "./review/review"; +import { UserReviewsResolver } from "./user/resolver"; +import { User } from "./user/user"; +import { buildFederatedSchema } from "../helpers/buildFederatedSchema"; + +export async function listen(port: number): Promise { + const schema = await buildFederatedSchema({ + resolvers: [ReviewsResolver, ProductReviewsResolver, UserReviewsResolver], + orphanedTypes: [User, Review, Product], + }); + + const server = new ApolloServer({ schema }); + + const { url } = await startStandaloneServer(server, { listen: { port } }); + console.log(`Reviews service ready at ${url}`); + + return url; +} diff --git a/examples/apollo-federation-2/reviews/product/product.ts b/examples/apollo-federation-2/reviews/product/product.ts new file mode 100644 index 000000000..22f1588dc --- /dev/null +++ b/examples/apollo-federation-2/reviews/product/product.ts @@ -0,0 +1,11 @@ +import { Directive, Field, ObjectType } from "type-graphql"; + +@Directive("@extends") +@Directive(`@key(fields: "upc")`) +@Directive("@interfaceObject") +@ObjectType() +export class Product { + @Directive("@external") + @Field() + upc!: string; +} diff --git a/examples/apollo-federation-2/reviews/product/resolver.ts b/examples/apollo-federation-2/reviews/product/resolver.ts new file mode 100644 index 000000000..15f800ee1 --- /dev/null +++ b/examples/apollo-federation-2/reviews/product/resolver.ts @@ -0,0 +1,12 @@ +import { FieldResolver, Resolver, Root } from "type-graphql"; +import { Product } from "./product"; +import { reviews } from "../review/data"; +import { Review } from "../review/review"; + +@Resolver(_of => Product) +export class ProductReviewsResolver { + @FieldResolver(() => [Review]) + async reviews(@Root() product: Product): Promise { + return reviews.filter(review => review.product.upc === product.upc); + } +} diff --git a/examples/apollo-federation-2/reviews/review/data.ts b/examples/apollo-federation-2/reviews/review/data.ts new file mode 100644 index 000000000..c6e9ed0fc --- /dev/null +++ b/examples/apollo-federation-2/reviews/review/data.ts @@ -0,0 +1,62 @@ +import { Review } from "./review"; +import { Product } from "../product/product"; +import { User } from "../user/user"; + +function createReview(reviewData: Partial) { + return Object.assign(new Review(), reviewData); +} + +function createUser(userData: Partial) { + return Object.assign(new User(), userData); +} + +function createProduct(productData: Partial) { + return Object.assign(new Product(), productData); +} + +export const reviews: Review[] = [ + createReview({ + id: "1", + author: createUser({ + id: "1", + username: "@ada", + }), + product: createProduct({ + upc: "1", + }), + body: "Love it!", + }), + createReview({ + id: "2", + author: createUser({ + id: "1", + username: "@ada", + }), + product: createProduct({ + upc: "2", + }), + body: "Too expensive.", + }), + createReview({ + id: "3", + author: createUser({ + id: "2", + username: "@complete", + }), + product: createProduct({ + upc: "3", + }), + body: "Could be better.", + }), + createReview({ + id: "4", + author: createUser({ + id: "2", + username: "@complete", + }), + product: createProduct({ + upc: "1", + }), + body: "Prefer something else.", + }), +]; diff --git a/examples/apollo-federation-2/reviews/review/resolver.ts b/examples/apollo-federation-2/reviews/review/resolver.ts new file mode 100644 index 000000000..eb59bf84b --- /dev/null +++ b/examples/apollo-federation-2/reviews/review/resolver.ts @@ -0,0 +1,11 @@ +import { FieldResolver, Resolver } from "type-graphql"; +import { reviews } from "./data"; +import { Review } from "./review"; + +@Resolver(_of => Review) +export class ReviewsResolver { + @FieldResolver(_returns => [Review]) + async reviews(): Promise { + return reviews; + } +} diff --git a/examples/apollo-federation-2/reviews/review/review.ts b/examples/apollo-federation-2/reviews/review/review.ts new file mode 100644 index 000000000..24c74e7ab --- /dev/null +++ b/examples/apollo-federation-2/reviews/review/review.ts @@ -0,0 +1,20 @@ +import { Directive, Field, ID, ObjectType } from "type-graphql"; +import { Product } from "../product/product"; +import { User } from "../user/user"; + +@Directive(`@key(fields: "id")`) +@ObjectType() +export class Review { + @Field(_type => ID) + id!: string; + + @Field() + body!: string; + + @Directive(`@provides(fields: "username")`) + @Field() + author!: User; + + @Field() + product!: Product; +} diff --git a/examples/apollo-federation-2/reviews/user/resolver.ts b/examples/apollo-federation-2/reviews/user/resolver.ts new file mode 100644 index 000000000..ae1858d3d --- /dev/null +++ b/examples/apollo-federation-2/reviews/user/resolver.ts @@ -0,0 +1,12 @@ +import { FieldResolver, Resolver, Root } from "type-graphql"; +import { User } from "./user"; +import { reviews } from "../review/data"; +import { Review } from "../review/review"; + +@Resolver(_of => User) +export class UserReviewsResolver { + @FieldResolver(_returns => [Review]) + async reviews(@Root() user: User): Promise { + return reviews.filter(review => review.author.id === user.id); + } +} diff --git a/examples/apollo-federation-2/reviews/user/user.ts b/examples/apollo-federation-2/reviews/user/user.ts new file mode 100644 index 000000000..8a1eb5eef --- /dev/null +++ b/examples/apollo-federation-2/reviews/user/user.ts @@ -0,0 +1,12 @@ +import { Directive, Field, ID, ObjectType } from "type-graphql"; + +@Directive(`@key(fields: "id")`) +@ObjectType() +export class User { + @Field(_type => ID) + id!: string; + + @Directive("@external") + @Field() + username!: string; +} diff --git a/examples/apollo-federation-2/schema.graphql b/examples/apollo-federation-2/schema.graphql new file mode 100644 index 000000000..65ba384e2 --- /dev/null +++ b/examples/apollo-federation-2/schema.graphql @@ -0,0 +1,57 @@ +# ----------------------------------------------- +# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!! +# !!! DO NOT MODIFY THIS FILE BY YOURSELF !!! +# ----------------------------------------------- + +type Dining implements Product { + height: String! + inStock: Boolean! + name: String! + price: Float! + reviews: [Review!]! + shippingEstimate: Float! + upc: String! + weight: Float! +} + +interface Product { + inStock: Boolean! + name: String! + price: Float! + reviews: [Review!]! + shippingEstimate: Float! + upc: String! + weight: Float! +} + +type Query { + me: User! + topProducts(first: Float! = 5): [Product!]! +} + +type Review { + author: User! + body: String! + id: ID! + product: Product! + reviews: [Review!]! +} + +type Seating implements Product { + inStock: Boolean! + name: String! + price: Float! + reviews: [Review!]! + seats: Float! + shippingEstimate: Float! + upc: String! + weight: Float! +} + +type User { + birthDate: String! + id: ID! + name: String! + reviews: [Review!]! + username: String! +} diff --git a/examples/apollo-federation/accounts/data.ts b/examples/apollo-federation/accounts/data.ts index 0b4f3e096..fde6e39b3 100644 --- a/examples/apollo-federation/accounts/data.ts +++ b/examples/apollo-federation/accounts/data.ts @@ -1,4 +1,8 @@ -import User from "./user"; +import { User } from "./user"; + +function createUser(userData: Partial) { + return Object.assign(new User(), userData); +} export const users: User[] = [ createUser({ @@ -14,7 +18,3 @@ export const users: User[] = [ username: "@complete", }), ]; - -function createUser(userData: Partial) { - return Object.assign(new User(), userData); -} diff --git a/examples/apollo-federation/accounts/index.ts b/examples/apollo-federation/accounts/index.ts index d1952c9bd..46aed9d78 100644 --- a/examples/apollo-federation/accounts/index.ts +++ b/examples/apollo-federation/accounts/index.ts @@ -1,11 +1,12 @@ -import { ApolloServer } from "apollo-server"; - -import AccountsResolver from "./resolver"; -import User from "./user"; -import { buildFederatedSchema } from "../helpers/buildFederatedSchema"; -import { resolveUserReference } from "./user-reference"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { AccountsResolver } from "./resolver"; +import { User } from "./user"; +import { resolveUserReference } from "./user.reference"; +import { buildFederatedSchema } from "../helpers"; export async function listen(port: number): Promise { + // Build TypeGraphQL executable schema const schema = await buildFederatedSchema( { resolvers: [AccountsResolver], @@ -16,13 +17,11 @@ export async function listen(port: number): Promise { }, ); - const server = new ApolloServer({ - schema, - tracing: false, - playground: true, - }); + // Create GraphQL server + const server = new ApolloServer({ schema }); - const { url } = await server.listen({ port }); + // Start server + const { url } = await startStandaloneServer(server, { listen: { port } }); console.log(`Accounts service ready at ${url}`); return url; diff --git a/examples/apollo-federation/accounts/resolver.ts b/examples/apollo-federation/accounts/resolver.ts index cd6a9f257..1f92764f5 100644 --- a/examples/apollo-federation/accounts/resolver.ts +++ b/examples/apollo-federation/accounts/resolver.ts @@ -1,11 +1,10 @@ -import { Resolver, Query } from "../../../src"; - -import User from "./user"; +import { Query, Resolver } from "type-graphql"; import { users } from "./data"; +import { User } from "./user"; -@Resolver(of => User) -export default class AccountsResolver { - @Query(returns => User) +@Resolver(_of => User) +export class AccountsResolver { + @Query(_returns => User) me(): User { return users[0]; } diff --git a/examples/apollo-federation/accounts/user.reference.ts b/examples/apollo-federation/accounts/user.reference.ts new file mode 100644 index 000000000..3d7112253 --- /dev/null +++ b/examples/apollo-federation/accounts/user.reference.ts @@ -0,0 +1,6 @@ +import { users } from "./data"; +import { type User } from "./user"; + +export async function resolveUserReference(reference: Pick): Promise { + return users.find(u => u.id === reference.id)!; +} diff --git a/examples/apollo-federation/accounts/user.ts b/examples/apollo-federation/accounts/user.ts index 3e74c425a..e27525801 100644 --- a/examples/apollo-federation/accounts/user.ts +++ b/examples/apollo-federation/accounts/user.ts @@ -1,17 +1,17 @@ -import { Field, ObjectType, Directive, ID } from "../../../src"; +import { Directive, Field, ID, ObjectType } from "type-graphql"; @Directive(`@key(fields: "id")`) @ObjectType() -export default class User { - @Field(type => ID) - id: string; +export class User { + @Field(_type => ID) + id!: string; @Field() - username: string; + username!: string; @Field() - name: string; + name!: string; @Field() - birthDate: string; + birthDate!: string; } diff --git a/examples/apollo-federation/examples.graphql b/examples/apollo-federation/examples.graphql index 45dca094f..38474e680 100644 --- a/examples/apollo-federation/examples.graphql +++ b/examples/apollo-federation/examples.graphql @@ -13,6 +13,7 @@ query { product { name } + body } } } diff --git a/examples/apollo-federation/helpers/buildFederatedSchema.ts b/examples/apollo-federation/helpers/buildFederatedSchema.ts index 494b703ac..74c3858bc 100644 --- a/examples/apollo-federation/helpers/buildFederatedSchema.ts +++ b/examples/apollo-federation/helpers/buildFederatedSchema.ts @@ -1,30 +1,26 @@ -import { specifiedDirectives } from "graphql"; -import federationDirectives from "@apollo/federation/dist/directives"; +import { buildSubgraphSchema } from "@apollo/subgraph"; +import { type IResolvers, printSchemaWithDirectives } from "@graphql-tools/utils"; import gql from "graphql-tag"; -import { - printSchema, - buildFederatedSchema as buildApolloFederationSchema, -} from "@apollo/federation"; -import { addResolversToSchema, GraphQLResolverMap } from "apollo-graphql"; -import { buildSchema, BuildSchemaOptions, createResolversMap } from "../../../src"; +import deepMerge from "lodash.merge"; +import { type BuildSchemaOptions, buildSchema, createResolversMap } from "type-graphql"; export async function buildFederatedSchema( options: Omit, - referenceResolvers?: GraphQLResolverMap, + referenceResolvers?: IResolvers, ) { + // Build TypeGraphQL executable schema const schema = await buildSchema({ ...options, - directives: [...specifiedDirectives, ...federationDirectives, ...(options.directives || [])], + // Disable check to allow schemas without query, etc... skipCheck: true, }); - const federatedSchema = buildApolloFederationSchema({ - typeDefs: gql(printSchema(schema)), - resolvers: createResolversMap(schema) as any, + // Build Apollo Subgraph schema + const federatedSchema = buildSubgraphSchema({ + typeDefs: gql(printSchemaWithDirectives(schema)), + // Merge schema's resolvers with reference resolvers + resolvers: deepMerge(createResolversMap(schema) as any, referenceResolvers), }); - if (referenceResolvers) { - addResolversToSchema(federatedSchema, referenceResolvers); - } return federatedSchema; } diff --git a/examples/apollo-federation/helpers/index.ts b/examples/apollo-federation/helpers/index.ts new file mode 100644 index 000000000..9778f65bc --- /dev/null +++ b/examples/apollo-federation/helpers/index.ts @@ -0,0 +1 @@ +export * from "./buildFederatedSchema"; diff --git a/examples/apollo-federation/index.ts b/examples/apollo-federation/index.ts index 50b333f07..bcea48095 100644 --- a/examples/apollo-federation/index.ts +++ b/examples/apollo-federation/index.ts @@ -1,36 +1,35 @@ import "reflect-metadata"; -import { ApolloGateway } from "@apollo/gateway"; -import { ApolloServer } from "apollo-server"; - +import path from "node:path"; +import { ApolloGateway, IntrospectAndCompose } from "@apollo/gateway"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { emitSchemaDefinitionFile } from "type-graphql"; import * as accounts from "./accounts"; -import * as reviews from "./reviews"; -import * as products from "./products"; import * as inventory from "./inventory"; +import * as products from "./products"; +import * as reviews from "./reviews"; async function bootstrap() { - const serviceList = [ - { name: "accounts", url: await accounts.listen(3001) }, - { name: "reviews", url: await reviews.listen(3002) }, - { name: "products", url: await products.listen(3003) }, - { name: "inventory", url: await inventory.listen(3004) }, - ]; - const gateway = new ApolloGateway({ - serviceList, + supergraphSdl: new IntrospectAndCompose({ + subgraphs: [ + { name: "accounts", url: await accounts.listen(4001) }, + { name: "reviews", url: await reviews.listen(4002) }, + { name: "products", url: await products.listen(4003) }, + { name: "inventory", url: await inventory.listen(4004) }, + ], + }), }); - const { schema, executor } = await gateway.load(); + // Create GraphQL server + const server = new ApolloServer({ gateway }); - const server = new ApolloServer({ - schema, - executor, - tracing: false, - playground: true, - }); + // Start server + const { url } = await startStandaloneServer(server, { listen: { port: 4000 } }); + console.log(`Apollo Gateway ready at ${url}`); - server.listen({ port: 3000 }).then(({ url }) => { - console.log(`Apollo Gateway ready at ${url}`); - }); + // Create 'schema.graphql' file with schema definition in current directory + await emitSchemaDefinitionFile(path.resolve(__dirname, "schema.graphql"), gateway.schema!); } bootstrap().catch(console.error); diff --git a/examples/apollo-federation/inventory/index.ts b/examples/apollo-federation/inventory/index.ts index f32c6f5a7..d30100b0a 100644 --- a/examples/apollo-federation/inventory/index.ts +++ b/examples/apollo-federation/inventory/index.ts @@ -1,11 +1,12 @@ -import { ApolloServer } from "apollo-server"; - -import InventoryResolver from "./resolver"; -import Product from "./product"; -import { resolveProductReference } from "./product-reference"; -import { buildFederatedSchema } from "../helpers/buildFederatedSchema"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { Product } from "./product"; +import { resolveProductReference } from "./product.reference"; +import { InventoryResolver } from "./resolver"; +import { buildFederatedSchema } from "../helpers"; export async function listen(port: number): Promise { + // Build TypeGraphQL executable schema const schema = await buildFederatedSchema( { resolvers: [InventoryResolver], @@ -16,13 +17,11 @@ export async function listen(port: number): Promise { }, ); - const server = new ApolloServer({ - schema, - tracing: false, - playground: true, - }); + // Create GraphQL server + const server = new ApolloServer({ schema }); - const { url } = await server.listen({ port }); + // Start server + const { url } = await startStandaloneServer(server, { listen: { port } }); console.log(`Inventory service ready at ${url}`); return url; diff --git a/examples/apollo-federation/inventory/product.reference.ts b/examples/apollo-federation/inventory/product.reference.ts new file mode 100644 index 000000000..4dbdca1e7 --- /dev/null +++ b/examples/apollo-federation/inventory/product.reference.ts @@ -0,0 +1,18 @@ +import { inventory } from "./data"; +import { Product } from "./product"; + +export async function resolveProductReference( + reference: Pick, +): Promise { + const found = inventory.find(i => i.upc === reference.upc); + + if (!found) { + return; + } + + // eslint-disable-next-line consistent-return + return Object.assign(new Product(), { + ...reference, + ...found, + }); +} diff --git a/examples/apollo-federation/inventory/product.ts b/examples/apollo-federation/inventory/product.ts index a758b5a5a..5deed5557 100644 --- a/examples/apollo-federation/inventory/product.ts +++ b/examples/apollo-federation/inventory/product.ts @@ -1,21 +1,21 @@ -import { ObjectType, Directive, Field } from "../../../src"; +import { Directive, Field, ObjectType } from "type-graphql"; @ObjectType() @Directive("@extends") @Directive(`@key(fields: "upc")`) -export default class Product { +export class Product { @Field() @Directive("@external") - upc: string; + upc!: string; @Field() @Directive("@external") - weight: number; + weight!: number; @Field() @Directive("@external") - price: number; + price!: number; @Field() - inStock: boolean; + inStock!: boolean; } diff --git a/examples/apollo-federation/inventory/resolver.ts b/examples/apollo-federation/inventory/resolver.ts index 7f1612a84..b04e01196 100644 --- a/examples/apollo-federation/inventory/resolver.ts +++ b/examples/apollo-federation/inventory/resolver.ts @@ -1,18 +1,17 @@ -import { Resolver, FieldResolver, Directive, Root } from "../../../src"; +import { Directive, FieldResolver, Resolver, Root } from "type-graphql"; +import { Product } from "./product"; -import Product from "./product"; - -@Resolver(of => Product) -export default class InventoryResolver { +@Resolver(_of => Product) +export class InventoryResolver { @Directive(`@requires(fields: "price weight")`) - @FieldResolver(returns => Number) + @FieldResolver(_returns => Number) async shippingEstimate(@Root() product: Product): Promise { - // free for expensive items + // Free for expensive items if (product.price > 1000) { return 0; } - // estimate is based on weight + // Estimate is based on weight return product.weight * 0.5; } } diff --git a/examples/apollo-federation/products/data.ts b/examples/apollo-federation/products/data.ts index 9f98968fe..af885b760 100644 --- a/examples/apollo-federation/products/data.ts +++ b/examples/apollo-federation/products/data.ts @@ -1,4 +1,8 @@ -import Product from "./product"; +import { Product } from "./product"; + +function createProduct(productData: Partial) { + return Object.assign(new Product(), productData); +} export const products: Product[] = [ createProduct({ @@ -20,7 +24,3 @@ export const products: Product[] = [ weight: 50, }), ]; - -function createProduct(productData: Partial) { - return Object.assign(new Product(), productData); -} diff --git a/examples/apollo-federation/products/index.ts b/examples/apollo-federation/products/index.ts index 33ad7d773..4907cdccf 100644 --- a/examples/apollo-federation/products/index.ts +++ b/examples/apollo-federation/products/index.ts @@ -1,11 +1,12 @@ -import { ApolloServer } from "apollo-server"; - -import ProductsResolver from "./resolver"; -import Product from "./product"; -import { resolveProductReference } from "./product-reference"; -import { buildFederatedSchema } from "../helpers/buildFederatedSchema"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { Product } from "./product"; +import { resolveProductReference } from "./product.reference"; +import { ProductsResolver } from "./resolver"; +import { buildFederatedSchema } from "../helpers"; export async function listen(port: number): Promise { + // Build TypeGraphQL executable schema const schema = await buildFederatedSchema( { resolvers: [ProductsResolver], @@ -16,14 +17,11 @@ export async function listen(port: number): Promise { }, ); - const server = new ApolloServer({ - schema, - tracing: false, - playground: true, - }); - - const { url } = await server.listen({ port }); + // Create GraphQL server + const server = new ApolloServer({ schema }); + // Start server + const { url } = await startStandaloneServer(server, { listen: { port } }); console.log(`Products service ready at ${url}`); return url; diff --git a/examples/apollo-federation/products/product.reference.ts b/examples/apollo-federation/products/product.reference.ts new file mode 100644 index 000000000..e6488b6c5 --- /dev/null +++ b/examples/apollo-federation/products/product.reference.ts @@ -0,0 +1,8 @@ +import { products } from "./data"; +import { type Product } from "./product"; + +export async function resolveProductReference( + reference: Pick, +): Promise { + return products.find(p => p.upc === reference.upc); +} diff --git a/examples/apollo-federation/products/product.ts b/examples/apollo-federation/products/product.ts index 4761234d5..05d3460a9 100644 --- a/examples/apollo-federation/products/product.ts +++ b/examples/apollo-federation/products/product.ts @@ -1,17 +1,17 @@ -import { ObjectType, Directive, Field } from "../../../src"; +import { Directive, Field, ObjectType } from "type-graphql"; @Directive(`@key(fields: "upc")`) @ObjectType() -export default class Product { +export class Product { @Field() - upc: string; + upc!: string; @Field() - name: string; + name!: string; @Field() - price: number; + price!: number; @Field() - weight: number; + weight!: number; } diff --git a/examples/apollo-federation/products/resolver.ts b/examples/apollo-federation/products/resolver.ts index 70d60c306..047cf52cb 100644 --- a/examples/apollo-federation/products/resolver.ts +++ b/examples/apollo-federation/products/resolver.ts @@ -1,11 +1,10 @@ -import { Resolver, Query, Arg } from "../../../src"; - -import Product from "./product"; +import { Arg, Query, Resolver } from "type-graphql"; import { products } from "./data"; +import { Product } from "./product"; -@Resolver(of => Product) -export default class ProductsResolver { - @Query(returns => [Product]) +@Resolver(_of => Product) +export class ProductsResolver { + @Query(_returns => [Product]) async topProducts( @Arg("first", { defaultValue: 5 }) first: number, diff --git a/examples/apollo-federation/reviews/index.ts b/examples/apollo-federation/reviews/index.ts index f4176203d..bd20cdd7c 100644 --- a/examples/apollo-federation/reviews/index.ts +++ b/examples/apollo-federation/reviews/index.ts @@ -1,26 +1,22 @@ -import { ApolloServer } from "apollo-server"; - -import ReviewsResolver from "./review/resolver"; -import ProductReviewsResolver from "./product/resolver"; -import UserReviewsResolver from "./user/resolver"; -import Review from "./review/review"; -import User from "./user/user"; -import Product from "./product/product"; -import { buildFederatedSchema } from "../helpers/buildFederatedSchema"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { Product, ProductReviewsResolver } from "./product"; +import { Review, ReviewsResolver } from "./review"; +import { User, UserReviewsResolver } from "./user"; +import { buildFederatedSchema } from "../helpers"; export async function listen(port: number): Promise { + // Build TypeGraphQL executable schema const schema = await buildFederatedSchema({ resolvers: [ReviewsResolver, ProductReviewsResolver, UserReviewsResolver], orphanedTypes: [User, Review, Product], }); - const server = new ApolloServer({ - schema, - tracing: false, - playground: true, - }); + // Create GraphQL server + const server = new ApolloServer({ schema }); - const { url } = await server.listen({ port }); + // Start server + const { url } = await startStandaloneServer(server, { listen: { port } }); console.log(`Reviews service ready at ${url}`); return url; diff --git a/examples/apollo-federation/reviews/product/index.ts b/examples/apollo-federation/reviews/product/index.ts new file mode 100644 index 000000000..c3ffabe68 --- /dev/null +++ b/examples/apollo-federation/reviews/product/index.ts @@ -0,0 +1,3 @@ +export * from "./product"; + +export * from "./resolver"; diff --git a/examples/apollo-federation/reviews/product/product.ts b/examples/apollo-federation/reviews/product/product.ts index 4a21adf8c..fb11058da 100644 --- a/examples/apollo-federation/reviews/product/product.ts +++ b/examples/apollo-federation/reviews/product/product.ts @@ -1,10 +1,10 @@ -import { ObjectType, Directive, Field } from "../../../../src"; +import { Directive, Field, ObjectType } from "type-graphql"; @Directive("@extends") @Directive(`@key(fields: "upc")`) @ObjectType() -export default class Product { +export class Product { @Directive("@external") @Field() - upc: string; + upc!: string; } diff --git a/examples/apollo-federation/reviews/product/resolver.ts b/examples/apollo-federation/reviews/product/resolver.ts index d60de4224..ffd36a68c 100644 --- a/examples/apollo-federation/reviews/product/resolver.ts +++ b/examples/apollo-federation/reviews/product/resolver.ts @@ -1,11 +1,9 @@ -import { Resolver, FieldResolver, Root } from "../../../../src"; +import { FieldResolver, Resolver, Root } from "type-graphql"; +import { Product } from "./product"; +import { Review, reviews } from "../review"; -import Product from "./product"; -import { reviews } from "../review/data"; -import Review from "../review/review"; - -@Resolver(of => Product) -export default class ProductReviewsResolver { +@Resolver(_of => Product) +export class ProductReviewsResolver { @FieldResolver(() => [Review]) async reviews(@Root() product: Product): Promise { return reviews.filter(review => review.product.upc === product.upc); diff --git a/examples/apollo-federation/reviews/review/data.ts b/examples/apollo-federation/reviews/review/data.ts index 51ffd7c91..9d0c08750 100644 --- a/examples/apollo-federation/reviews/review/data.ts +++ b/examples/apollo-federation/reviews/review/data.ts @@ -1,6 +1,18 @@ -import Review from "./review"; -import User from "../user/user"; -import Product from "../product/product"; +import { Review } from "./review"; +import { Product } from "../product"; +import { User } from "../user"; + +function createReview(reviewData: Partial) { + return Object.assign(new Review(), reviewData); +} + +function createUser(userData: Partial) { + return Object.assign(new User(), userData); +} + +function createProduct(productData: Partial) { + return Object.assign(new Product(), productData); +} export const reviews: Review[] = [ createReview({ @@ -48,15 +60,3 @@ export const reviews: Review[] = [ body: "Prefer something else.", }), ]; - -function createReview(reviewData: Partial) { - return Object.assign(new Review(), reviewData); -} - -function createUser(userData: Partial) { - return Object.assign(new User(), userData); -} - -function createProduct(productData: Partial) { - return Object.assign(new Product(), productData); -} diff --git a/examples/apollo-federation/reviews/review/index.ts b/examples/apollo-federation/reviews/review/index.ts new file mode 100644 index 000000000..6fa85506b --- /dev/null +++ b/examples/apollo-federation/reviews/review/index.ts @@ -0,0 +1,3 @@ +export * from "./data"; +export * from "./resolver"; +export * from "./review"; diff --git a/examples/apollo-federation/reviews/review/resolver.ts b/examples/apollo-federation/reviews/review/resolver.ts index c20b8a2ba..eb59bf84b 100644 --- a/examples/apollo-federation/reviews/review/resolver.ts +++ b/examples/apollo-federation/reviews/review/resolver.ts @@ -1,11 +1,10 @@ -import { Resolver, FieldResolver } from "../../../../src"; - -import Review from "./review"; +import { FieldResolver, Resolver } from "type-graphql"; import { reviews } from "./data"; +import { Review } from "./review"; -@Resolver(of => Review) -export default class ReviewsResolver { - @FieldResolver(returns => [Review]) +@Resolver(_of => Review) +export class ReviewsResolver { + @FieldResolver(_returns => [Review]) async reviews(): Promise { return reviews; } diff --git a/examples/apollo-federation/reviews/review/review.ts b/examples/apollo-federation/reviews/review/review.ts index bf1ea52c5..de8a376f6 100644 --- a/examples/apollo-federation/reviews/review/review.ts +++ b/examples/apollo-federation/reviews/review/review.ts @@ -1,21 +1,20 @@ -import { Directive, ObjectType, Field, ID } from "../../../../src"; - -import User from "../user/user"; -import Product from "../product/product"; +import { Directive, Field, ID, ObjectType } from "type-graphql"; +import { Product } from "../product"; +import { User } from "../user"; @Directive(`@key(fields: "id")`) @ObjectType() -export default class Review { - @Field(type => ID) - id: string; +export class Review { + @Field(_type => ID) + id!: string; @Field() - body: string; + body!: string; @Directive(`@provides(fields: "username")`) @Field() - author: User; + author!: User; @Field() - product: Product; + product!: Product; } diff --git a/examples/apollo-federation/reviews/user/index.ts b/examples/apollo-federation/reviews/user/index.ts new file mode 100644 index 000000000..5dcb340c1 --- /dev/null +++ b/examples/apollo-federation/reviews/user/index.ts @@ -0,0 +1,2 @@ +export * from "./resolver"; +export * from "./user"; diff --git a/examples/apollo-federation/reviews/user/resolver.ts b/examples/apollo-federation/reviews/user/resolver.ts index cc9de8d4b..d4a8b23bc 100644 --- a/examples/apollo-federation/reviews/user/resolver.ts +++ b/examples/apollo-federation/reviews/user/resolver.ts @@ -1,12 +1,10 @@ -import { Resolver, FieldResolver, Root } from "../../../../src"; +import { FieldResolver, Resolver, Root } from "type-graphql"; +import { User } from "./user"; +import { Review, reviews } from "../review"; -import User from "./user"; -import Review from "../review/review"; -import { reviews } from "../review/data"; - -@Resolver(of => User) -export default class UserReviewsResolver { - @FieldResolver(returns => [Review]) +@Resolver(_of => User) +export class UserReviewsResolver { + @FieldResolver(_returns => [Review]) async reviews(@Root() user: User): Promise { return reviews.filter(review => review.author.id === user.id); } diff --git a/examples/apollo-federation/reviews/user/user.ts b/examples/apollo-federation/reviews/user/user.ts index cecb0358e..f159bf5f6 100644 --- a/examples/apollo-federation/reviews/user/user.ts +++ b/examples/apollo-federation/reviews/user/user.ts @@ -1,14 +1,14 @@ -import { Directive, ObjectType, Field, ID } from "../../../../src"; +import { Directive, Field, ID, ObjectType } from "type-graphql"; @Directive("@extends") @Directive(`@key(fields: "id")`) @ObjectType() -export default class User { +export class User { @Directive("@external") - @Field(type => ID) - id: string; + @Field(_type => ID) + id!: string; @Directive("@external") @Field() - username: string; + username!: string; } diff --git a/examples/apollo-federation/schema.graphql b/examples/apollo-federation/schema.graphql new file mode 100644 index 000000000..c7b3241cd --- /dev/null +++ b/examples/apollo-federation/schema.graphql @@ -0,0 +1,35 @@ +# ----------------------------------------------- +# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!! +# !!! DO NOT MODIFY THIS FILE BY YOURSELF !!! +# ----------------------------------------------- + +type Product { + inStock: Boolean! + name: String! + price: Float! + reviews: [Review!]! + shippingEstimate: Float! + upc: String! + weight: Float! +} + +type Query { + me: User! + topProducts(first: Float! = 5): [Product!]! +} + +type Review { + author: User! + body: String! + id: ID! + product: Product! + reviews: [Review!]! +} + +type User { + birthDate: String! + id: ID! + name: String! + reviews: [Review!]! + username: String! +} diff --git a/examples/authorization/auth-checker.ts b/examples/authorization/auth-checker.ts index 47d05d16f..9df2d0aa7 100644 --- a/examples/authorization/auth-checker.ts +++ b/examples/authorization/auth-checker.ts @@ -1,24 +1,20 @@ -import { AuthChecker } from "../../src"; +import { type AuthChecker } from "type-graphql"; +import { type Context } from "./context.type"; -import { Context } from "./context.interface"; - -// create auth checker function +// Auth checker function export const authChecker: AuthChecker = ({ context: { user } }, roles) => { - if (roles.length === 0) { - // if `@Authorized()`, check only if user exists - return user !== undefined; - } - // there are some roles defined now - + // Check user if (!user) { - // and if no user, restrict access + // No user, restrict access return false; } - if (user.roles.some(role => roles.includes(role))) { - // grant access if the roles overlap + + // Check '@Authorized()' + if (roles.length === 0) { + // Only authentication required return true; } - // no roles matched, restrict access - return false; + // Check '@Authorized(...)' roles overlap + return user.roles.some(role => roles.includes(role)); }; diff --git a/examples/authorization/context.interface.ts b/examples/authorization/context.type.ts similarity index 52% rename from examples/authorization/context.interface.ts rename to examples/authorization/context.type.ts index 095b5cf51..75412b3f7 100644 --- a/examples/authorization/context.interface.ts +++ b/examples/authorization/context.type.ts @@ -1,4 +1,4 @@ -import { User } from "./user.interface"; +import { type User } from "./user.type"; export interface Context { user?: User; diff --git a/examples/authorization/examples.gql b/examples/authorization/examples.gql deleted file mode 100644 index f57a92c28..000000000 --- a/examples/authorization/examples.gql +++ /dev/null @@ -1,36 +0,0 @@ -query GetPublicRecipes { - recipes { - title - description - averageRating - } -} - -query GetRecipesForAuthedUser { - recipes { - title - description - ingredients - averageRating - } -} - -query GetRecipesForAdmin { - recipes { - title - description - ingredients - averageRating - ratings - } -} - -mutation AddRecipeByAuthedUser { - addRecipe(title: "Sample Recipe") { - averageRating - } -} - -mutation DeleteRecipeByAdmin { - deleteRecipe(title: "Recipe 1") -} diff --git a/examples/extensions/examples.gql b/examples/authorization/examples.graphql similarity index 85% rename from examples/extensions/examples.gql rename to examples/authorization/examples.graphql index f57a92c28..669badc66 100644 --- a/examples/extensions/examples.gql +++ b/examples/authorization/examples.graphql @@ -6,7 +6,7 @@ query GetPublicRecipes { } } -query GetRecipesForAuthedUser { +query GetRecipesForAuthorizedUser { recipes { title description @@ -25,7 +25,7 @@ query GetRecipesForAdmin { } } -mutation AddRecipeByAuthedUser { +mutation AddRecipeByAuthorizedUser { addRecipe(title: "Sample Recipe") { averageRating } diff --git a/examples/authorization/index.ts b/examples/authorization/index.ts index 54c704b99..3f1666207 100644 --- a/examples/authorization/index.ts +++ b/examples/authorization/index.ts @@ -1,36 +1,41 @@ import "reflect-metadata"; -import { ApolloServer } from "apollo-server"; -import { buildSchema } from "../../src"; - -import { ExampleResolver } from "./resolver"; -import { Context } from "./context.interface"; +import path from "node:path"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { buildSchema } from "type-graphql"; import { authChecker } from "./auth-checker"; +import { type Context } from "./context.type"; +import { RecipeResolver } from "./recipe.resolver"; -void (async function bootstrap() { - // build TypeGraphQL executable schema +async function bootstrap() { + // Build TypeGraphQL executable schema const schema = await buildSchema({ - resolvers: [ExampleResolver], - authChecker, // register auth checking function + // Array of resolvers + resolvers: [RecipeResolver], + // Register auth checker function + authChecker, + // Create 'schema.graphql' file with schema definition in current directory + emitSchemaFile: path.resolve(__dirname, "schema.graphql"), }); // Create GraphQL server - const server = new ApolloServer({ - schema, - context: () => { - const ctx: Context = { - // create mocked user in context - // in real app you would be mapping user from `req.user` or sth - user: { - id: 1, - name: "Sample user", - roles: ["REGULAR"], - }, - }; - return ctx; - }, + const server = new ApolloServer({ schema }); + + // Start server + const { url } = await startStandaloneServer(server, { + listen: { port: 4000 }, + // Provide context for each request + context: async () => ({ + // Create mocked user in context + // In real app you would be mapping user from 'req.user' or sth + user: { + id: 1, + name: "Sample user", + roles: ["REGULAR"], + }, + }), }); + console.log(`GraphQL server ready at ${url}`); +} - // Start the server - const { url } = await server.listen(4000); - console.log(`Server is running, GraphQL Playground available at ${url}`); -})(); +bootstrap().catch(console.error); diff --git a/examples/authorization/recipe.helpers.ts b/examples/authorization/recipe.data.ts similarity index 100% rename from examples/authorization/recipe.helpers.ts rename to examples/authorization/recipe.data.ts index 3ff81b2e5..7734fcf45 100644 --- a/examples/authorization/recipe.helpers.ts +++ b/examples/authorization/recipe.data.ts @@ -1,5 +1,9 @@ import { Recipe } from "./recipe.type"; +function createRecipe(recipeData: Partial): Recipe { + return Object.assign(new Recipe(), recipeData); +} + export const sampleRecipes = [ createRecipe({ title: "Recipe 1", @@ -19,7 +23,3 @@ export const sampleRecipes = [ ratings: [4, 4, 5, 5, 4], }), ]; - -function createRecipe(recipeData: Partial): Recipe { - return Object.assign(new Recipe(), recipeData); -} diff --git a/examples/authorization/resolver.ts b/examples/authorization/recipe.resolver.ts similarity index 65% rename from examples/authorization/resolver.ts rename to examples/authorization/recipe.resolver.ts index c548f2565..6113dc0a7 100644 --- a/examples/authorization/resolver.ts +++ b/examples/authorization/recipe.resolver.ts @@ -1,19 +1,18 @@ -import { Resolver, Query, Authorized, Mutation, Arg } from "../../src"; - +import { Arg, Authorized, Mutation, Query, Resolver } from "type-graphql"; +import { sampleRecipes } from "./recipe.data"; import { Recipe } from "./recipe.type"; -import { sampleRecipes } from "./recipe.helpers"; @Resolver() -export class ExampleResolver { +export class RecipeResolver { private recipesData: Recipe[] = sampleRecipes.slice(); - // anyone can read recipes collection - @Query(returns => [Recipe]) + // Anyone can read recipes collection + @Query(_returns => [Recipe]) async recipes(): Promise { - return await this.recipesData; + return this.recipesData; } - @Authorized() // only logged users can add new recipe + @Authorized() // Only authenticated users can add new recipe @Mutation() addRecipe( @Arg("title") title: string, @@ -25,10 +24,11 @@ export class ExampleResolver { ratings: [], }); this.recipesData.push(newRecipe); + return newRecipe; } - @Authorized("ADMIN") // only admin can remove the published recipe + @Authorized("ADMIN") // Only 'ADMIN' users can remove published recipe @Mutation() deleteRecipe(@Arg("title") title: string): boolean { const foundRecipeIndex = this.recipesData.findIndex(it => it.title === title); @@ -36,6 +36,7 @@ export class ExampleResolver { return false; } this.recipesData.splice(foundRecipeIndex, 1); + return true; } } diff --git a/examples/authorization/recipe.type.ts b/examples/authorization/recipe.type.ts index 79b8ec26b..41446d247 100644 --- a/examples/authorization/recipe.type.ts +++ b/examples/authorization/recipe.type.ts @@ -1,23 +1,26 @@ -import { ObjectType, Field, Int, Authorized, Float } from "../../src"; +import { Authorized, Field, Float, Int, ObjectType } from "type-graphql"; @ObjectType() export class Recipe { @Field() - title: string; + title!: string; @Field({ nullable: true }) description?: string; - @Authorized() // restrict access to ingredients only for logged users (paid subscription?) - @Field(type => [String]) - ingredients: string[]; + @Authorized() // Restrict access only for authenticated users + @Field(_type => [String]) + ingredients!: string[]; - @Authorized("ADMIN") // restrict access to rates details for admin only - @Field(type => [Int]) - ratings: number[]; + @Authorized("ADMIN") // Restrict access only for 'ADMIN' users + @Field(_type => [Int]) + ratings!: number[]; - @Field(type => Float, { nullable: true }) + @Field(_type => Float, { nullable: true }) get averageRating(): number | null { + if (!this.ratings.length) { + return null; + } return this.ratings.reduce((a, b) => a + b, 0) / this.ratings.length; } } diff --git a/examples/graphql-modules/recipe/recipe.schema.gql b/examples/authorization/schema.graphql similarity index 61% rename from examples/graphql-modules/recipe/recipe.schema.gql rename to examples/authorization/schema.graphql index 4a91dd950..153382571 100644 --- a/examples/graphql-modules/recipe/recipe.schema.gql +++ b/examples/authorization/schema.graphql @@ -3,22 +3,19 @@ # !!! DO NOT MODIFY THIS FILE BY YOURSELF !!! # ----------------------------------------------- -""" -The javascript `Date` as string. Type represents date and time as the ISO Date string. -""" -scalar DateTime +type Mutation { + addRecipe(description: String, title: String!): Recipe! + deleteRecipe(title: String!): Boolean! +} type Query { recipes: [Recipe!]! } type Recipe { - creationDate: DateTime! + averageRating: Float description: String - id: Int! + ingredients: [String!]! + ratings: [Int!]! title: String! } - -type User { - recipes: [Recipe!]! -} diff --git a/examples/authorization/user.interface.ts b/examples/authorization/user.type.ts similarity index 100% rename from examples/authorization/user.interface.ts rename to examples/authorization/user.type.ts diff --git a/examples/automatic-validation/examples.gql b/examples/automatic-validation/examples.gql deleted file mode 100644 index 8dd36fe8a..000000000 --- a/examples/automatic-validation/examples.gql +++ /dev/null @@ -1,33 +0,0 @@ -query GetRecipes { - recipes { - title - description - creationDate - } -} - -mutation CorrectAddRecipe { - addRecipe(input: { - title: "Correct title" - description: "Very very very very very very very very long description" - }) { - creationDate - } -} - -mutation AddRecipeWithoutDesc { - addRecipe(input: { - title: "Correct title" - }) { - creationDate - } -} - -mutation IncorrectAddRecipe { - addRecipe(input: { - title: "Correct title" - description: "Too short description" - }) { - creationDate - } -} diff --git a/examples/automatic-validation/examples.graphql b/examples/automatic-validation/examples.graphql new file mode 100644 index 000000000..ea57cf16b --- /dev/null +++ b/examples/automatic-validation/examples.graphql @@ -0,0 +1,30 @@ +query GetRecipes { + recipes { + title + description + creationDate + } +} + +mutation CorrectAddRecipe { + addRecipe( + input: { + title: "Correct title" + description: "Very very very very very very very very long description" + } + ) { + creationDate + } +} + +mutation AddRecipeWithoutDesc { + addRecipe(input: { title: "Correct title" }) { + creationDate + } +} + +mutation IncorrectAddRecipe { + addRecipe(input: { title: "Correct title", description: "Too short description" }) { + creationDate + } +} diff --git a/examples/automatic-validation/helpers.ts b/examples/automatic-validation/helpers.ts index 333f3e653..83261c9d0 100644 --- a/examples/automatic-validation/helpers.ts +++ b/examples/automatic-validation/helpers.ts @@ -1,4 +1,4 @@ -import { Recipe } from "./recipe-type"; +import { type Recipe } from "./recipe.type"; export function generateRecipes(count: number): Recipe[] { return new Array(count).fill(null).map( diff --git a/examples/automatic-validation/index.ts b/examples/automatic-validation/index.ts index 431e38b42..93137379f 100644 --- a/examples/automatic-validation/index.ts +++ b/examples/automatic-validation/index.ts @@ -1,21 +1,27 @@ import "reflect-metadata"; -import { ApolloServer } from "apollo-server"; -import { buildSchema } from "../../src"; - -import { RecipeResolver } from "./recipe-resolver"; +import path from "node:path"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { buildSchema } from "type-graphql"; +import { RecipeResolver } from "./recipe.resolver"; async function bootstrap() { - // build TypeGraphQL executable schema + // Build TypeGraphQL executable schema const schema = await buildSchema({ + // Array of resolvers resolvers: [RecipeResolver], + // Create 'schema.graphql' file with schema definition in current directory + emitSchemaFile: path.resolve(__dirname, "schema.graphql"), + // remember to turn on validation! + validate: true, }); // Create GraphQL server const server = new ApolloServer({ schema }); - // Start the server - const { url } = await server.listen(4000); - console.log(`Server is running, GraphQL Playground available at ${url}`); + // Start server + const { url } = await startStandaloneServer(server, { listen: { port: 4000 } }); + console.log(`GraphQL server ready at ${url}`); } -bootstrap(); +bootstrap().catch(console.error); diff --git a/examples/automatic-validation/recipe-input.ts b/examples/automatic-validation/recipe.input.ts similarity index 50% rename from examples/automatic-validation/recipe-input.ts rename to examples/automatic-validation/recipe.input.ts index df9e852a9..2f3998fd6 100644 --- a/examples/automatic-validation/recipe-input.ts +++ b/examples/automatic-validation/recipe.input.ts @@ -1,13 +1,12 @@ -import { MaxLength, Length } from "class-validator"; -import { InputType, Field } from "../../src"; - -import { Recipe } from "./recipe-type"; +import { Length, MaxLength } from "class-validator"; +import { Field, InputType } from "type-graphql"; +import { type Recipe } from "./recipe.type"; @InputType() export class RecipeInput implements Partial { @Field() @MaxLength(30) - title: string; + title!: string; @Field({ nullable: true }) @Length(30, 255) diff --git a/examples/custom-validation/recipe-resolver.ts b/examples/automatic-validation/recipe.resolver.ts similarity index 63% rename from examples/custom-validation/recipe-resolver.ts rename to examples/automatic-validation/recipe.resolver.ts index f49b45a88..9d402008e 100644 --- a/examples/custom-validation/recipe-resolver.ts +++ b/examples/automatic-validation/recipe.resolver.ts @@ -1,22 +1,21 @@ -import { Resolver, Query, Arg, Mutation, Args } from "../../src"; - -import { Recipe } from "./recipe-type"; -import { RecipeInput } from "./recipe-input"; -import { RecipesArguments } from "./recipes-arguments"; +import { Arg, Args, Mutation, Query, Resolver } from "type-graphql"; import { generateRecipes } from "./helpers"; +import { RecipeInput } from "./recipe.input"; +import { Recipe } from "./recipe.type"; +import { RecipesArguments } from "./recipes.arguments"; -@Resolver(of => Recipe) +@Resolver(_of => Recipe) export class RecipeResolver { private readonly items: Recipe[] = generateRecipes(100); - @Query(returns => [Recipe]) + @Query(_returns => [Recipe]) async recipes(@Args() options: RecipesArguments): Promise { const start: number = options.skip; const end: number = options.skip + options.take; - return await this.items.slice(start, end); + return this.items.slice(start, end); } - @Mutation(returns => Recipe) + @Mutation(_returns => Recipe) async addRecipe(@Arg("input") recipeInput: RecipeInput): Promise { const recipe = new Recipe(); recipe.description = recipeInput.description; diff --git a/examples/automatic-validation/recipe-type.ts b/examples/automatic-validation/recipe.type.ts similarity index 56% rename from examples/automatic-validation/recipe-type.ts rename to examples/automatic-validation/recipe.type.ts index 25e8e8462..6352ee241 100644 --- a/examples/automatic-validation/recipe-type.ts +++ b/examples/automatic-validation/recipe.type.ts @@ -1,13 +1,13 @@ -import { Field, ObjectType } from "../../src"; +import { Field, ObjectType } from "type-graphql"; @ObjectType() export class Recipe { @Field() - title: string; + title!: string; @Field({ nullable: true }) description?: string; @Field() - creationDate: Date; + creationDate!: Date; } diff --git a/examples/automatic-validation/recipes-arguments.ts b/examples/automatic-validation/recipes-arguments.ts deleted file mode 100644 index a83c854ba..000000000 --- a/examples/automatic-validation/recipes-arguments.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Max, Min } from "class-validator"; -import { ArgsType, Field, Int } from "../../src"; - -@ArgsType() -export class RecipesArguments { - @Field(type => Int) - @Min(0) - skip: number = 0; - - @Field(type => Int) - @Min(1) - @Max(50) - take: number = 10; -} diff --git a/examples/automatic-validation/recipes.arguments.ts b/examples/automatic-validation/recipes.arguments.ts new file mode 100644 index 000000000..70d25d1a6 --- /dev/null +++ b/examples/automatic-validation/recipes.arguments.ts @@ -0,0 +1,14 @@ +import { Max, Min } from "class-validator"; +import { ArgsType, Field, Int } from "type-graphql"; + +@ArgsType() +export class RecipesArguments { + @Field(_type => Int) + @Min(0) + skip = 0; + + @Field(_type => Int) + @Min(1) + @Max(50) + take = 10; +} diff --git a/examples/automatic-validation/schema.graphql b/examples/automatic-validation/schema.graphql new file mode 100644 index 000000000..e67963eeb --- /dev/null +++ b/examples/automatic-validation/schema.graphql @@ -0,0 +1,28 @@ +# ----------------------------------------------- +# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!! +# !!! DO NOT MODIFY THIS FILE BY YOURSELF !!! +# ----------------------------------------------- + +""" +A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar.This scalar is serialized to a string in ISO 8601 format and parsed from a string in ISO 8601 format. +""" +scalar DateTimeISO + +type Mutation { + addRecipe(input: RecipeInput!): Recipe! +} + +type Query { + recipes(skip: Int! = 0, take: Int! = 10): [Recipe!]! +} + +type Recipe { + creationDate: DateTimeISO! + description: String + title: String! +} + +input RecipeInput { + description: String + title: String! +} diff --git a/examples/custom-validation/examples.gql b/examples/custom-validation/examples.gql deleted file mode 100644 index 8dd36fe8a..000000000 --- a/examples/custom-validation/examples.gql +++ /dev/null @@ -1,33 +0,0 @@ -query GetRecipes { - recipes { - title - description - creationDate - } -} - -mutation CorrectAddRecipe { - addRecipe(input: { - title: "Correct title" - description: "Very very very very very very very very long description" - }) { - creationDate - } -} - -mutation AddRecipeWithoutDesc { - addRecipe(input: { - title: "Correct title" - }) { - creationDate - } -} - -mutation IncorrectAddRecipe { - addRecipe(input: { - title: "Correct title" - description: "Too short description" - }) { - creationDate - } -} diff --git a/examples/custom-validation/examples.graphql b/examples/custom-validation/examples.graphql new file mode 100644 index 000000000..ea57cf16b --- /dev/null +++ b/examples/custom-validation/examples.graphql @@ -0,0 +1,30 @@ +query GetRecipes { + recipes { + title + description + creationDate + } +} + +mutation CorrectAddRecipe { + addRecipe( + input: { + title: "Correct title" + description: "Very very very very very very very very long description" + } + ) { + creationDate + } +} + +mutation AddRecipeWithoutDesc { + addRecipe(input: { title: "Correct title" }) { + creationDate + } +} + +mutation IncorrectAddRecipe { + addRecipe(input: { title: "Correct title", description: "Too short description" }) { + creationDate + } +} diff --git a/examples/custom-validation/helpers.ts b/examples/custom-validation/helpers.ts index 333f3e653..83261c9d0 100644 --- a/examples/custom-validation/helpers.ts +++ b/examples/custom-validation/helpers.ts @@ -1,4 +1,4 @@ -import { Recipe } from "./recipe-type"; +import { type Recipe } from "./recipe.type"; export function generateRecipes(count: number): Recipe[] { return new Array(count).fill(null).map( diff --git a/examples/custom-validation/index.ts b/examples/custom-validation/index.ts index e070a89c5..7dd9395ee 100644 --- a/examples/custom-validation/index.ts +++ b/examples/custom-validation/index.ts @@ -1,22 +1,24 @@ import "reflect-metadata"; -import { ApolloServer } from "apollo-server"; -import * as joiful from "joiful"; -import * as path from "path"; -import { buildSchema } from "../../src"; - -import { RecipeResolver } from "./recipe-resolver"; +import path from "node:path"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import joiful from "joiful"; +import { buildSchema } from "type-graphql"; +import { RecipeResolver } from "./recipe.resolver"; async function bootstrap() { - // build TypeGraphQL executable schema + // Build TypeGraphQL executable schema const schema = await buildSchema({ + // Array of resolvers resolvers: [RecipeResolver], - emitSchemaFile: path.resolve(__dirname, "schema.gql"), - // custom validate function - validate: (argValue, argType) => { - // call joiful validate + // Create 'schema.graphql' file with schema definition in current directory + emitSchemaFile: path.resolve(__dirname, "schema.graphql"), + // Custom validate function + validateFn: (argValue, _argType) => { + // Call joiful validate const { error } = joiful.validate(argValue); if (error) { - // throw error on failed validation + // Throw error if validation failed throw error; } }, @@ -25,9 +27,9 @@ async function bootstrap() { // Create GraphQL server const server = new ApolloServer({ schema }); - // Start the server - const { url } = await server.listen(4000); - console.log(`Server is running, GraphQL Playground available at ${url}`); + // Start server + const { url } = await startStandaloneServer(server, { listen: { port: 4000 } }); + console.log(`GraphQL server ready at ${url}`); } -bootstrap(); +bootstrap().catch(console.error); diff --git a/examples/custom-validation/recipe-input.ts b/examples/custom-validation/recipe-input.ts deleted file mode 100644 index d956aa0db..000000000 --- a/examples/custom-validation/recipe-input.ts +++ /dev/null @@ -1,17 +0,0 @@ -import * as Joiful from "joiful"; -import { InputType, Field } from "../../src"; - -import { Recipe } from "./recipe-type"; - -@InputType() -export class RecipeInput implements Partial { - @Field() - // use decorators for Joi - @(Joiful.string().required().max(30)) - title: string; - - @Field({ nullable: true }) - // use decorators for Joi - @(Joiful.string().min(30).max(255)) - description?: string; -} diff --git a/examples/custom-validation/recipe.input.ts b/examples/custom-validation/recipe.input.ts new file mode 100644 index 000000000..7ade7b499 --- /dev/null +++ b/examples/custom-validation/recipe.input.ts @@ -0,0 +1,16 @@ +import Joiful from "joiful"; +import { Field, InputType } from "type-graphql"; +import { type Recipe } from "./recipe.type"; + +@InputType() +export class RecipeInput implements Partial { + @Field() + // Joi decorator + @Joiful.string().required().max(30) + title!: string; + + @Field({ nullable: true }) + // Joi decorator + @Joiful.string().min(30).max(255) + description?: string; +} diff --git a/examples/automatic-validation/recipe-resolver.ts b/examples/custom-validation/recipe.resolver.ts similarity index 63% rename from examples/automatic-validation/recipe-resolver.ts rename to examples/custom-validation/recipe.resolver.ts index f49b45a88..9d402008e 100644 --- a/examples/automatic-validation/recipe-resolver.ts +++ b/examples/custom-validation/recipe.resolver.ts @@ -1,22 +1,21 @@ -import { Resolver, Query, Arg, Mutation, Args } from "../../src"; - -import { Recipe } from "./recipe-type"; -import { RecipeInput } from "./recipe-input"; -import { RecipesArguments } from "./recipes-arguments"; +import { Arg, Args, Mutation, Query, Resolver } from "type-graphql"; import { generateRecipes } from "./helpers"; +import { RecipeInput } from "./recipe.input"; +import { Recipe } from "./recipe.type"; +import { RecipesArguments } from "./recipes.arguments"; -@Resolver(of => Recipe) +@Resolver(_of => Recipe) export class RecipeResolver { private readonly items: Recipe[] = generateRecipes(100); - @Query(returns => [Recipe]) + @Query(_returns => [Recipe]) async recipes(@Args() options: RecipesArguments): Promise { const start: number = options.skip; const end: number = options.skip + options.take; - return await this.items.slice(start, end); + return this.items.slice(start, end); } - @Mutation(returns => Recipe) + @Mutation(_returns => Recipe) async addRecipe(@Arg("input") recipeInput: RecipeInput): Promise { const recipe = new Recipe(); recipe.description = recipeInput.description; diff --git a/examples/custom-validation/recipe-type.ts b/examples/custom-validation/recipe.type.ts similarity index 56% rename from examples/custom-validation/recipe-type.ts rename to examples/custom-validation/recipe.type.ts index 25e8e8462..6352ee241 100644 --- a/examples/custom-validation/recipe-type.ts +++ b/examples/custom-validation/recipe.type.ts @@ -1,13 +1,13 @@ -import { Field, ObjectType } from "../../src"; +import { Field, ObjectType } from "type-graphql"; @ObjectType() export class Recipe { @Field() - title: string; + title!: string; @Field({ nullable: true }) description?: string; @Field() - creationDate: Date; + creationDate!: Date; } diff --git a/examples/custom-validation/recipes-arguments.ts b/examples/custom-validation/recipes-arguments.ts deleted file mode 100644 index d79174e56..000000000 --- a/examples/custom-validation/recipes-arguments.ts +++ /dev/null @@ -1,15 +0,0 @@ -import * as Joiful from "joiful"; -import { ArgsType, Field, Int } from "../../src"; - -@ArgsType() -export class RecipesArguments { - @Field(type => Int) - // use decorators for Joi - @(Joiful.number().min(0)) - skip: number = 0; - - @Field(type => Int) - // use decorators for Joi - @(Joiful.number().min(1).max(50)) - take: number = 10; -} diff --git a/examples/custom-validation/recipes.arguments.ts b/examples/custom-validation/recipes.arguments.ts new file mode 100644 index 000000000..bd40ca84d --- /dev/null +++ b/examples/custom-validation/recipes.arguments.ts @@ -0,0 +1,15 @@ +import Joiful from "joiful"; +import { ArgsType, Field, Int } from "type-graphql"; + +@ArgsType() +export class RecipesArguments { + @Field(_type => Int) + // use decorators for Joi + @Joiful.number().min(0) + skip = 0; + + @Field(_type => Int) + // use decorators for Joi + @Joiful.number().min(1).max(50) + take = 10; +} diff --git a/examples/custom-validation/schema.gql b/examples/custom-validation/schema.graphql similarity index 90% rename from examples/custom-validation/schema.gql rename to examples/custom-validation/schema.graphql index f55329ee1..9df721e46 100644 --- a/examples/custom-validation/schema.gql +++ b/examples/custom-validation/schema.graphql @@ -13,7 +13,7 @@ type Mutation { } type Query { - recipes(skip: Int = 0, take: Int = 10): [Recipe!]! + recipes(skip: Int! = 0, take: Int! = 10): [Recipe!]! } type Recipe { diff --git a/examples/dev.js b/examples/dev.js deleted file mode 100644 index fccfe8e7c..000000000 --- a/examples/dev.js +++ /dev/null @@ -1,23 +0,0 @@ -// require("./apollo-cache/index.ts"); -// require("./apollo-federation/index.ts"); -// require("./authorization/index.ts"); -// require("./automatic-validation/index.ts"); -// require("./custom-validation/index.ts"); -// require("./enums-and-unions/index.ts"); -// require("./extensions/index.ts"); -// require("./generic-types/index.ts"); -// require("./graphql-modules/src/index.ts"); -// require("./interfaces-inheritance/index.ts"); -// require("./middlewares-custom-decorators/index.ts"); -// require("./mikro-orm/index.ts"); -// require("./mixin-classes/index.ts"); -// require("./query-complexity/index.ts"); -// require("./redis-subscriptions/index.ts"); -// require("./resolvers-inheritance/index.ts"); -// require("./simple-subscriptions/index.ts"); -// require("./simple-usage/index.ts"); -// require("./typegoose/index.ts"); -// require("./typeorm-basic-usage/index.ts"); -// require("./typeorm-lazy-relations/index.ts"); -// require("./using-container/index.ts"); -// require("./using-scoped-container/index.ts"); diff --git a/examples/enums-and-unions/cook.samples.ts b/examples/enums-and-unions/cook.data.ts similarity index 91% rename from examples/enums-and-unions/cook.samples.ts rename to examples/enums-and-unions/cook.data.ts index 2e83266b6..a4bf55ee1 100644 --- a/examples/enums-and-unions/cook.samples.ts +++ b/examples/enums-and-unions/cook.data.ts @@ -1,16 +1,16 @@ import { Cook } from "./cook.type"; +function createCook(cookData: Partial): Cook { + return Object.assign(new Cook(), cookData); +} + export const sampleCooks = [ createCook({ name: "Gordon Ramsay", yearsOfExperience: 21, }), createCook({ - name: "Kim Kardashian", + name: "Marilyn Monroe", yearsOfExperience: 1, }), ]; - -function createCook(cookData: Partial): Cook { - return Object.assign(new Cook(), cookData); -} diff --git a/examples/enums-and-unions/cook.type.ts b/examples/enums-and-unions/cook.type.ts index 7d8b5a8f5..700119e71 100644 --- a/examples/enums-and-unions/cook.type.ts +++ b/examples/enums-and-unions/cook.type.ts @@ -1,10 +1,10 @@ -import { Field, ObjectType, Int } from "../../src"; +import { Field, Int, ObjectType } from "type-graphql"; @ObjectType() export class Cook { @Field() - name: string; + name!: string; - @Field(type => Int) - yearsOfExperience: number; + @Field(_type => Int) + yearsOfExperience!: number; } diff --git a/examples/enums-and-unions/difficulty.enum.ts b/examples/enums-and-unions/difficulty.enum.ts index bbdfba25a..ea79e069b 100644 --- a/examples/enums-and-unions/difficulty.enum.ts +++ b/examples/enums-and-unions/difficulty.enum.ts @@ -1,4 +1,4 @@ -import { registerEnumType } from "../../src"; +import { registerEnumType } from "type-graphql"; export enum Difficulty { Beginner, diff --git a/examples/enums-and-unions/examples.gql b/examples/enums-and-unions/examples.graphql similarity index 100% rename from examples/enums-and-unions/examples.gql rename to examples/enums-and-unions/examples.graphql diff --git a/examples/enums-and-unions/index.ts b/examples/enums-and-unions/index.ts index cab9e91d7..902b40821 100644 --- a/examples/enums-and-unions/index.ts +++ b/examples/enums-and-unions/index.ts @@ -1,21 +1,25 @@ import "reflect-metadata"; -import { ApolloServer } from "apollo-server"; -import { buildSchema } from "../../src"; - +import path from "node:path"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { buildSchema } from "type-graphql"; import { ExampleResolver } from "./resolver"; async function bootstrap() { - // build TypeGraphQL executable schema + // Build TypeGraphQL executable schema const schema = await buildSchema({ + // Array of resolvers resolvers: [ExampleResolver], + // Create 'schema.graphql' file with schema definition in current directory + emitSchemaFile: path.resolve(__dirname, "schema.graphql"), }); // Create GraphQL server const server = new ApolloServer({ schema }); - // Start the server - const { url } = await server.listen(4000); - console.log(`Server is running, GraphQL Playground available at ${url}`); + // Start server + const { url } = await startStandaloneServer(server, { listen: { port: 4000 } }); + console.log(`GraphQL server ready at ${url}`); } -bootstrap(); +bootstrap().catch(console.error); diff --git a/examples/enums-and-unions/recipe.samples.ts b/examples/enums-and-unions/recipe.data.ts similarity index 96% rename from examples/enums-and-unions/recipe.samples.ts rename to examples/enums-and-unions/recipe.data.ts index f26e542d9..1e0bb81f6 100644 --- a/examples/enums-and-unions/recipe.samples.ts +++ b/examples/enums-and-unions/recipe.data.ts @@ -1,6 +1,10 @@ -import { Recipe } from "./recipe.type"; +import { sampleCooks } from "./cook.data"; import { Difficulty } from "./difficulty.enum"; -import { sampleCooks } from "./cook.samples"; +import { Recipe } from "./recipe.type"; + +function createRecipe(recipeData: Partial): Recipe { + return Object.assign(new Recipe(), recipeData); +} export const sampleRecipes = [ createRecipe({ @@ -37,7 +41,3 @@ export const sampleRecipes = [ cook: sampleCooks[0], }), ]; - -function createRecipe(recipeData: Partial): Recipe { - return Object.assign(new Recipe(), recipeData); -} diff --git a/examples/enums-and-unions/recipe.type.ts b/examples/enums-and-unions/recipe.type.ts index 3e0eed498..bc6beffa6 100644 --- a/examples/enums-and-unions/recipe.type.ts +++ b/examples/enums-and-unions/recipe.type.ts @@ -1,22 +1,21 @@ -import { Field, ObjectType } from "../../src"; - -import { Difficulty } from "./difficulty.enum"; +import { Field, ObjectType } from "type-graphql"; import { Cook } from "./cook.type"; +import { Difficulty } from "./difficulty.enum"; @ObjectType() export class Recipe { @Field() - title: string; + title!: string; @Field({ nullable: true }) description?: string; - @Field(type => [String]) - ingredients: string[]; + @Field(_type => [String]) + ingredients!: string[]; - @Field(type => Difficulty) - preparationDifficulty: Difficulty; + @Field(_type => Difficulty) + preparationDifficulty!: Difficulty; @Field() - cook: Cook; + cook!: Cook; } diff --git a/examples/enums-and-unions/resolver.ts b/examples/enums-and-unions/resolver.ts index a0b68fc5c..c2adca125 100644 --- a/examples/enums-and-unions/resolver.ts +++ b/examples/enums-and-unions/resolver.ts @@ -1,20 +1,20 @@ -import { Resolver, Query, Arg } from "../../src"; - -import { Recipe } from "./recipe.type"; -import { sampleRecipes } from "./recipe.samples"; +import { Arg, Query, Resolver } from "type-graphql"; +import { sampleCooks } from "./cook.data"; +import { type Cook } from "./cook.type"; import { Difficulty } from "./difficulty.enum"; +import { sampleRecipes } from "./recipe.data"; +import { Recipe } from "./recipe.type"; import { SearchResult } from "./search-result.union"; -import { Cook } from "./cook.type"; -import { sampleCooks } from "./cook.samples"; @Resolver() export class ExampleResolver { private recipesData: Recipe[] = sampleRecipes; + private cooks: Cook[] = sampleCooks; - @Query(returns => [Recipe]) + @Query(_returns => [Recipe]) async recipes( - @Arg("difficulty", type => Difficulty, { nullable: true }) difficulty?: Difficulty, + @Arg("difficulty", _type => Difficulty, { nullable: true }) difficulty?: Difficulty, ): Promise { if (!difficulty) { return this.recipesData; @@ -23,7 +23,7 @@ export class ExampleResolver { return this.recipesData.filter(recipe => recipe.preparationDifficulty === difficulty); } - @Query(returns => [SearchResult]) + @Query(_returns => [SearchResult]) async search(@Arg("cookName") cookName: string): Promise> { const recipes = this.recipesData.filter(recipe => recipe.cook.name.match(cookName)); const cooks = this.cooks.filter(cook => cook.name.match(cookName)); diff --git a/examples/enums-and-unions/schema.graphql b/examples/enums-and-unions/schema.graphql new file mode 100644 index 000000000..cdc234ac3 --- /dev/null +++ b/examples/enums-and-unions/schema.graphql @@ -0,0 +1,35 @@ +# ----------------------------------------------- +# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!! +# !!! DO NOT MODIFY THIS FILE BY YOURSELF !!! +# ----------------------------------------------- + +type Cook { + name: String! + yearsOfExperience: Int! +} + +""" +All possible preparation difficulty levels +""" +enum Difficulty { + Beginner + Easy + Hard + MasterChef + Medium +} + +type Query { + recipes(difficulty: Difficulty): [Recipe!]! + search(cookName: String!): [SearchResult!]! +} + +type Recipe { + cook: Cook! + description: String + ingredients: [String!]! + preparationDifficulty: Difficulty! + title: String! +} + +union SearchResult = Cook | Recipe diff --git a/examples/enums-and-unions/search-result.union.ts b/examples/enums-and-unions/search-result.union.ts index 495072003..718c7649d 100644 --- a/examples/enums-and-unions/search-result.union.ts +++ b/examples/enums-and-unions/search-result.union.ts @@ -1,7 +1,6 @@ -import { createUnionType } from "../../src"; - -import { Recipe } from "./recipe.type"; +import { createUnionType } from "type-graphql"; import { Cook } from "./cook.type"; +import { Recipe } from "./recipe.type"; export const SearchResult = createUnionType({ name: "SearchResult", diff --git a/examples/extensions/context.interface.ts b/examples/extensions/context.type.ts similarity index 52% rename from examples/extensions/context.interface.ts rename to examples/extensions/context.type.ts index 095b5cf51..75412b3f7 100644 --- a/examples/extensions/context.interface.ts +++ b/examples/extensions/context.type.ts @@ -1,4 +1,4 @@ -import { User } from "./user.interface"; +import { type User } from "./user.type"; export interface Context { user?: User; diff --git a/examples/extensions/examples.graphql b/examples/extensions/examples.graphql new file mode 100644 index 000000000..4139e48dd --- /dev/null +++ b/examples/extensions/examples.graphql @@ -0,0 +1,19 @@ +query GetRecipes { + recipes { + title + description + ingredients + averageRating + ratings + } +} + +mutation AddRecipe { + addRecipe(title: "Sample Recipe") { + averageRating + } +} + +mutation DeleteRecipe { + deleteRecipe(title: "Recipe 1") +} diff --git a/examples/extensions/helpers/config.extractors.ts b/examples/extensions/helpers/config.extractors.ts index 630b277b3..ebdce39c3 100644 --- a/examples/extensions/helpers/config.extractors.ts +++ b/examples/extensions/helpers/config.extractors.ts @@ -1,9 +1,12 @@ -import { GraphQLResolveInfo, GraphQLFieldConfig, GraphQLObjectTypeConfig } from "graphql"; +import { + type GraphQLFieldConfig, + type GraphQLObjectTypeConfig, + type GraphQLResolveInfo, +} from "graphql"; export const extractFieldConfig = (info: GraphQLResolveInfo): GraphQLFieldConfig => { - const { type, extensions, description, deprecationReason } = info.parentType.getFields()[ - info.fieldName - ]; + const { type, extensions, description, deprecationReason } = + info.parentType.getFields()[info.fieldName]; return { type, diff --git a/examples/extensions/index.ts b/examples/extensions/index.ts index 8d8e01e9e..b874c6ac9 100644 --- a/examples/extensions/index.ts +++ b/examples/extensions/index.ts @@ -1,36 +1,44 @@ import "reflect-metadata"; -import { ApolloServer } from "apollo-server"; -import Container from "typedi"; -import { buildSchema } from "../../src"; - -import { ExampleResolver } from "./resolver"; -import { Context } from "./context.interface"; +import path from "node:path"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { buildSchema } from "type-graphql"; +import { Container } from "typedi"; +import { type Context } from "./context.type"; import { LoggerMiddleware } from "./logger.middleware"; +import { RecipeResolver } from "./resolver"; -void (async function bootstrap() { - // build TypeGraphQL executable schema +async function bootstrap() { + // Build TypeGraphQL executable schema const schema = await buildSchema({ + // Array of resolvers + resolvers: [RecipeResolver], + // IOC container container: Container, - resolvers: [ExampleResolver], + // Global middleware globalMiddlewares: [LoggerMiddleware], + // Create 'schema.graphql' file with schema definition in current directory + emitSchemaFile: path.resolve(__dirname, "schema.graphql"), }); // Create GraphQL server - const server = new ApolloServer({ + const server = new ApolloServer({ schema, - context: () => { - const ctx: Context = { - // example user - user: { - id: 123, - name: "Sample user", - }, - }; - return ctx; - }, }); - // Start the server - const { url } = await server.listen(4000); - console.log(`Server is running, GraphQL Playground available at ${url}`); -})(); + // Start server + const { url } = await startStandaloneServer(server, { + listen: { port: 4000 }, + // Provide context + context: async () => ({ + // Example user + user: { + id: 123, + name: "Sample user", + }, + }), + }); + console.log(`GraphQL server ready at ${url}`); +} + +bootstrap().catch(console.error); diff --git a/examples/extensions/log-message.decorator.ts b/examples/extensions/log-message.decorator.ts index b8a66ddb6..54e93c70a 100644 --- a/examples/extensions/log-message.decorator.ts +++ b/examples/extensions/log-message.decorator.ts @@ -1,4 +1,4 @@ -import { Extensions } from "../../src"; +import { Extensions } from "type-graphql"; interface LogOptions { message: string; @@ -6,7 +6,7 @@ interface LogOptions { } export function LogMessage(messageOrOptions: string | LogOptions) { - // parse the parameters of the custom decorator + // Parse the parameters of the custom decorator const log: LogOptions = typeof messageOrOptions === "string" ? { @@ -15,6 +15,6 @@ export function LogMessage(messageOrOptions: string | LogOptions) { } : messageOrOptions; - // return the `@Extensions` decorator with a prepared property + // Return the '@Extensions' decorator with a prepared property return Extensions({ log }); } diff --git a/examples/extensions/logger.middleware.ts b/examples/extensions/logger.middleware.ts index 835fda8b0..207144752 100644 --- a/examples/extensions/logger.middleware.ts +++ b/examples/extensions/logger.middleware.ts @@ -1,14 +1,22 @@ +import { + type GraphQLFieldConfig, + type GraphQLObjectTypeConfig, + type GraphQLResolveInfo, +} from "graphql"; +import { type MiddlewareInterface, type NextFn, type ResolverData } from "type-graphql"; import { Service } from "typedi"; -import { GraphQLResolveInfo, GraphQLFieldConfig, GraphQLObjectTypeConfig } from "graphql"; -import { MiddlewareInterface, NextFn, ResolverData } from "../../src"; - +import { type Context } from "./context.type"; import { extractFieldConfig, extractParentTypeConfig } from "./helpers/config.extractors"; -import { Context } from "./context.interface"; import { Logger } from "./logger.service"; +interface LoggerConfig { + message?: string; + level?: number; +} + const extractLoggerExtensionsFromConfig = ( config: GraphQLObjectTypeConfig | GraphQLFieldConfig, -) => (config.extensions && config.extensions.log) || {}; +): LoggerConfig => (config.extensions && (config.extensions.log as LoggerConfig)) || {}; const getLoggerExtensions = (info: GraphQLResolveInfo) => { const fieldConfig = extractFieldConfig(info); diff --git a/examples/extensions/logger.service.ts b/examples/extensions/logger.service.ts index 8b7623a7b..cd9b1d354 100644 --- a/examples/extensions/logger.service.ts +++ b/examples/extensions/logger.service.ts @@ -2,8 +2,7 @@ import { Service } from "typedi"; @Service() export class Logger { - log(...args: any[]) { - // replace with more sophisticated solution :) + log(...args: unknown[]) { console.log(...args); } } diff --git a/examples/extensions/helpers/recipe.ts b/examples/extensions/recipe.data.ts similarity index 93% rename from examples/extensions/helpers/recipe.ts rename to examples/extensions/recipe.data.ts index ff6ae3403..7734fcf45 100644 --- a/examples/extensions/helpers/recipe.ts +++ b/examples/extensions/recipe.data.ts @@ -1,4 +1,8 @@ -import { Recipe } from "../recipe.type"; +import { Recipe } from "./recipe.type"; + +function createRecipe(recipeData: Partial): Recipe { + return Object.assign(new Recipe(), recipeData); +} export const sampleRecipes = [ createRecipe({ @@ -19,7 +23,3 @@ export const sampleRecipes = [ ratings: [4, 4, 5, 5, 4], }), ]; - -function createRecipe(recipeData: Partial): Recipe { - return Object.assign(new Recipe(), recipeData); -} diff --git a/examples/extensions/recipe.type.ts b/examples/extensions/recipe.type.ts index 192c72ef4..b549b081e 100644 --- a/examples/extensions/recipe.type.ts +++ b/examples/extensions/recipe.type.ts @@ -1,29 +1,31 @@ -import { ObjectType, Extensions, Field, Int, Float } from "../../src"; - +import { Extensions, Field, Float, Int, ObjectType } from "type-graphql"; import { LogMessage } from "./log-message.decorator"; @ObjectType() -// log a message when any Recipe field is accessed +// Log a message when any Recipe field is accessed @LogMessage("Recipe field accessed") export class Recipe { @Field() - title: string; + title!: string; @Field({ nullable: true }) description?: string; - @Field(type => [String]) - // We can use raw Extensions decorator if we want - @Extensions({ log: { message: "ingredients field accessed", level: 0 } }) - ingredients: string[]; + @Field(_type => [String]) + // Use raw 'Extensions' decorator + @Extensions({ log: { message: "Ingredients field accessed", level: 0 } }) + ingredients!: string[]; - // this will override the object type log message + // Override the object type log message @LogMessage("Ratings accessed") - @Field(type => [Int]) - ratings: number[]; + @Field(_type => [Int]) + ratings!: number[]; - @Field(type => Float, { nullable: true }) + @Field(_type => Float, { nullable: true }) get averageRating(): number | null { + if (!this.ratings.length) { + return null; + } return this.ratings.reduce((a, b) => a + b, 0) / this.ratings.length; } } diff --git a/examples/extensions/resolver.ts b/examples/extensions/resolver.ts index 4da36935a..8380d8ce6 100644 --- a/examples/extensions/resolver.ts +++ b/examples/extensions/resolver.ts @@ -1,16 +1,17 @@ -import { Resolver, Query, Mutation, Arg } from "../../src"; - +import { Arg, Mutation, Query, Resolver } from "type-graphql"; +import { Service } from "typedi"; import { LogMessage } from "./log-message.decorator"; +import { sampleRecipes } from "./recipe.data"; import { Recipe } from "./recipe.type"; -import { sampleRecipes } from "./helpers/recipe"; +@Service() @Resolver() -export class ExampleResolver { +export class RecipeResolver { private recipesData: Recipe[] = sampleRecipes.slice(); - @Query(returns => [Recipe]) + @Query(_returns => [Recipe]) async recipes(): Promise { - return await this.recipesData; + return this.recipesData; } @Mutation() diff --git a/examples/extensions/schema.graphql b/examples/extensions/schema.graphql new file mode 100644 index 000000000..153382571 --- /dev/null +++ b/examples/extensions/schema.graphql @@ -0,0 +1,21 @@ +# ----------------------------------------------- +# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!! +# !!! DO NOT MODIFY THIS FILE BY YOURSELF !!! +# ----------------------------------------------- + +type Mutation { + addRecipe(description: String, title: String!): Recipe! + deleteRecipe(title: String!): Boolean! +} + +type Query { + recipes: [Recipe!]! +} + +type Recipe { + averageRating: Float + description: String + ingredients: [String!]! + ratings: [Int!]! + title: String! +} diff --git a/examples/extensions/user.interface.ts b/examples/extensions/user.type.ts similarity index 100% rename from examples/extensions/user.interface.ts rename to examples/extensions/user.type.ts diff --git a/examples/generic-types/examples.gql b/examples/generic-types/examples.graphql similarity index 100% rename from examples/generic-types/examples.gql rename to examples/generic-types/examples.graphql diff --git a/examples/generic-types/index.ts b/examples/generic-types/index.ts index 4f1dfb4ce..76a69d3f5 100644 --- a/examples/generic-types/index.ts +++ b/examples/generic-types/index.ts @@ -1,23 +1,25 @@ import "reflect-metadata"; -import { ApolloServer } from "apollo-server"; -import * as path from "path"; -import { buildSchema } from "../../src"; - -import RecipeResolver from "./recipe.resolver"; +import path from "node:path"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { buildSchema } from "type-graphql"; +import { RecipeResolver } from "./recipe.resolver"; async function bootstrap() { + // Build TypeGraphQL executable schema const schema = await buildSchema({ + // Array of resolvers resolvers: [RecipeResolver], - emitSchemaFile: path.resolve(__dirname, "schema.gql"), + // Create 'schema.graphql' file with schema definition in current directory + emitSchemaFile: path.resolve(__dirname, "schema.graphql"), }); - const server = new ApolloServer({ - schema, - playground: true, - }); + // Create GraphQL server + const server = new ApolloServer({ schema }); - const { url } = await server.listen(4000); - console.log(`Server is running, GraphQL Playground available at ${url}`); + // Start server + const { url } = await startStandaloneServer(server, { listen: { port: 4000 } }); + console.log(`GraphQL server ready at ${url}`); } bootstrap().catch(console.error); diff --git a/examples/generic-types/paginated-response.type.ts b/examples/generic-types/paginated-response.type.ts index 948c52847..ea2736547 100644 --- a/examples/generic-types/paginated-response.type.ts +++ b/examples/generic-types/paginated-response.type.ts @@ -1,19 +1,19 @@ -import { ClassType, Field, ObjectType, Int } from "../../src"; +import { type ClassType, Field, Int, ObjectType } from "type-graphql"; -export default function PaginatedResponse( - itemsFieldValue: ClassType | String | Number | Boolean, +export function PaginatedResponse( + itemsFieldValue: ClassType | string | number | boolean, ) { - // `isAbstract` decorator option is mandatory to prevent registering in schema - @ObjectType({ isAbstract: true }) + @ObjectType() abstract class PaginatedResponseClass { - @Field(type => [itemsFieldValue]) - items: TItemsFieldValue[]; + @Field(_type => [itemsFieldValue]) + items!: TItemsFieldValue[]; - @Field(type => Int) - total: number; + @Field(_type => Int) + total!: number; @Field() - hasMore: boolean; + hasMore!: boolean; } + return PaginatedResponseClass; } diff --git a/examples/generic-types/recipe.samples.ts b/examples/generic-types/recipe.data.ts similarity index 75% rename from examples/generic-types/recipe.samples.ts rename to examples/generic-types/recipe.data.ts index 97839695b..b6b1356d0 100644 --- a/examples/generic-types/recipe.samples.ts +++ b/examples/generic-types/recipe.data.ts @@ -1,6 +1,6 @@ -import Recipe from "./recipe.type"; +import { type Recipe } from "./recipe.type"; -export default function createSampleRecipes(): Recipe[] { +export function createSampleRecipes(): Recipe[] { return [ { description: "Desc 1", diff --git a/examples/generic-types/recipe.resolver.ts b/examples/generic-types/recipe.resolver.ts index 92251718e..d0eac2d1f 100644 --- a/examples/generic-types/recipe.resolver.ts +++ b/examples/generic-types/recipe.resolver.ts @@ -1,22 +1,22 @@ -import { ObjectType, Query, Mutation, Arg, Int, Resolver } from "../../src"; +/* eslint-disable max-classes-per-file */ +import { Arg, Int, Mutation, ObjectType, Query, Resolver } from "type-graphql"; +import { PaginatedResponse } from "./paginated-response.type"; +import { createSampleRecipes } from "./recipe.data"; +import { Recipe } from "./recipe.type"; -import PaginatedResponse from "./paginated-response.type"; -import Recipe from "./recipe.type"; -import createSampleRecipes from "./recipe.samples"; - -// we need to create a temporary class for the abstract, generic class "instance" +// Create a temporary class for the abstract generic class 'instance' @ObjectType() class RecipesResponse extends PaginatedResponse(Recipe) { - // you can add more fields here if you need + // Add more fields here if needed } @Resolver() -export default class RecipeResolver { +export class RecipeResolver { private readonly recipes = createSampleRecipes(); @Query({ name: "recipes" }) getRecipes( - @Arg("first", type => Int, { nullable: true, defaultValue: 10 }) first: number, + @Arg("first", _type => Int, { nullable: true, defaultValue: 10 }) first: number, ): RecipesResponse { const total = this.recipes.length; return { diff --git a/examples/generic-types/recipe.type.ts b/examples/generic-types/recipe.type.ts index fa54fa4d6..30297fbdf 100644 --- a/examples/generic-types/recipe.type.ts +++ b/examples/generic-types/recipe.type.ts @@ -1,13 +1,13 @@ -import { Field, ObjectType, Int } from "../../src"; +import { Field, Int, ObjectType } from "type-graphql"; @ObjectType() -export default class Recipe { +export class Recipe { @Field() - title: string; + title!: string; - @Field() + @Field({ nullable: true }) description?: string; - @Field(type => [Int]) - ratings: number[]; + @Field(_type => [Int]) + ratings!: number[]; } diff --git a/examples/generic-types/schema.gql b/examples/generic-types/schema.graphql similarity index 95% rename from examples/generic-types/schema.gql rename to examples/generic-types/schema.graphql index 527ba055b..b3d613638 100644 --- a/examples/generic-types/schema.gql +++ b/examples/generic-types/schema.graphql @@ -12,7 +12,7 @@ type Query { } type Recipe { - description: String! + description: String ratings: [Int!]! title: String! } diff --git a/examples/graphql-modules/examples.gql b/examples/graphql-modules/examples.gql deleted file mode 100644 index 3b1f3f2fa..000000000 --- a/examples/graphql-modules/examples.gql +++ /dev/null @@ -1,42 +0,0 @@ -query GetRecipes { - recipes { - id - title - description - creationDate - } -} - -query GetRecipesWithAuthor { - recipes { - id - title - author { - id - name - email - age - } - } -} - -query GetUsers { - users { - id - name - email - age - } -} - -query GetUsersWithRecipes { - users { - id - name - recipes { - title - description - creationDate - } - } -} diff --git a/examples/graphql-modules/index.ts b/examples/graphql-modules/index.ts deleted file mode 100644 index 230c52f7a..000000000 --- a/examples/graphql-modules/index.ts +++ /dev/null @@ -1,28 +0,0 @@ -import "reflect-metadata"; -import { GraphQLModule } from "@graphql-modules/core"; -import { ApolloServer } from "apollo-server"; -import * as path from "path"; -import { emitSchemaDefinitionFile } from "../../src"; - -import RecipeModule from "./recipe/recipe.module"; -import UserModule from "./user/user.module"; - -async function bootstrap() { - // create main app module - const { schema } = new GraphQLModule({ - // join other sub-modules - imports: [RecipeModule, UserModule], - }); - // emit combined schema file - await emitSchemaDefinitionFile(path.resolve(__dirname, "../", "schema.gql"), schema); - - const server = new ApolloServer({ - schema, - playground: true, - }); - - const { url } = await server.listen(4000); - console.log(`Server is running, GraphQL Playground available at ${url}`); -} - -bootstrap().catch(console.error); diff --git a/examples/graphql-modules/recipe/recipe.module.ts b/examples/graphql-modules/recipe/recipe.module.ts deleted file mode 100644 index 7273733a4..000000000 --- a/examples/graphql-modules/recipe/recipe.module.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { GraphQLModule } from "@graphql-modules/core"; -import * as path from "path"; -import { buildSchemaSync } from "../../../src"; - -import RecipeResolver from "./recipe.resolver"; -import UserResolver from "./user.resolver"; -import RecipeService from "./recipe.service"; -import User from "./user.type"; - -const resolvers = [RecipeResolver, UserResolver] as const; - -// @ts-ignore -const RecipeModule = new GraphQLModule({ - providers: [RecipeService, ...resolvers], - extraSchemas: [ - buildSchemaSync({ - resolvers, - orphanedTypes: [User], - container: ({ context }) => RecipeModule.injector.getSessionInjector(context), - skipCheck: true, - emitSchemaFile: path.resolve(__dirname, "recipe.schema.gql"), - }), - ], -}); - -export default RecipeModule; diff --git a/examples/graphql-modules/recipe/recipe.resolver.ts b/examples/graphql-modules/recipe/recipe.resolver.ts deleted file mode 100644 index d1f221248..000000000 --- a/examples/graphql-modules/recipe/recipe.resolver.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Injectable } from "@graphql-modules/di"; -import { Resolver, Query } from "../../../src"; - -import Recipe from "./recipe.type"; -import RecipeService from "./recipe.service"; - -@Injectable() -@Resolver(of => Recipe) -export default class RecipeResolver { - constructor(private readonly recipeService: RecipeService) {} - - @Query(returns => [Recipe]) - recipes() { - return this.recipeService.getAll(); - } -} diff --git a/examples/graphql-modules/recipe/recipe.seed.ts b/examples/graphql-modules/recipe/recipe.seed.ts deleted file mode 100644 index 892738657..000000000 --- a/examples/graphql-modules/recipe/recipe.seed.ts +++ /dev/null @@ -1,26 +0,0 @@ -import Recipe from "./recipe.type"; - -export default function createRecipes(): Recipe[] { - return [ - { - id: 1, - title: "Spaghetti", - creationDate: new Date("2020-07-05T12:42:12Z"), - description: "Italian food", - authorId: 1, - }, - { - id: 2, - title: "Tortilla", - creationDate: new Date("2020-07-04T11:24:11Z"), - description: "Spanish food", - authorId: 1, - }, - { - id: 3, - title: "Hamburger", - creationDate: new Date("2020-07-03T15:32:22Z"), - authorId: 2, - }, - ]; -} diff --git a/examples/graphql-modules/recipe/recipe.service.ts b/examples/graphql-modules/recipe/recipe.service.ts deleted file mode 100644 index ae0d12d54..000000000 --- a/examples/graphql-modules/recipe/recipe.service.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Injectable } from "@graphql-modules/di"; - -import Recipe from "./recipe.type"; -import createRecipes from "./recipe.seed"; - -@Injectable() -export default class RecipeService { - private readonly recipes: Recipe[] = createRecipes(); - - getAll() { - return this.recipes; - } - - findById(id: number) { - return this.recipes.filter(it => it.authorId === id); - } -} diff --git a/examples/graphql-modules/recipe/recipe.type.ts b/examples/graphql-modules/recipe/recipe.type.ts deleted file mode 100644 index c11a3b9a5..000000000 --- a/examples/graphql-modules/recipe/recipe.type.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Field, ObjectType, Int } from "../../../src"; - -@ObjectType() -export default class Recipe { - @Field(type => Int) - id: number; - - @Field() - title: string; - - @Field({ nullable: true }) - description?: string; - - @Field() - creationDate: Date; - - authorId: number; -} diff --git a/examples/graphql-modules/recipe/user.resolver.ts b/examples/graphql-modules/recipe/user.resolver.ts deleted file mode 100644 index f00889a1d..000000000 --- a/examples/graphql-modules/recipe/user.resolver.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Injectable } from "@graphql-modules/di"; -import { Resolver, FieldResolver, Root } from "../../../src"; - -import User from "./user.type"; -import RecipeService from "./recipe.service"; - -@Injectable() -@Resolver(of => User) -export default class UserResolver { - constructor(private readonly recipeService: RecipeService) {} - - @FieldResolver() - recipes(@Root() user: User) { - return this.recipeService.findById(user.id); - } -} diff --git a/examples/graphql-modules/recipe/user.type.ts b/examples/graphql-modules/recipe/user.type.ts deleted file mode 100644 index 8e11f5121..000000000 --- a/examples/graphql-modules/recipe/user.type.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { ObjectType, Field } from "../../../src"; - -import Recipe from "./recipe.type"; - -@ObjectType() -export default class User { - id: number; - - @Field(type => [Recipe]) - recipes: Recipe[]; -} diff --git a/examples/graphql-modules/user/recipe.resolver.ts b/examples/graphql-modules/user/recipe.resolver.ts deleted file mode 100644 index b5156e362..000000000 --- a/examples/graphql-modules/user/recipe.resolver.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Injectable } from "@graphql-modules/di"; -import { Resolver, FieldResolver, Root } from "../../../src"; - -import UserService from "./user.service"; -import Recipe from "./recipe.type"; - -@Injectable() -@Resolver(of => Recipe) -export default class RecipeResolver { - constructor(private readonly userService: UserService) {} - - @FieldResolver() - author(@Root() recipe: Recipe) { - return this.userService.findById(recipe.authorId); - } -} diff --git a/examples/graphql-modules/user/recipe.type.ts b/examples/graphql-modules/user/recipe.type.ts deleted file mode 100644 index ad9f22ccc..000000000 --- a/examples/graphql-modules/user/recipe.type.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Field, ObjectType } from "../../../src"; - -import User from "./user.type"; - -@ObjectType() -export default class Recipe { - authorId: number; - - @Field() - author: User; -} diff --git a/examples/graphql-modules/user/user.module.ts b/examples/graphql-modules/user/user.module.ts deleted file mode 100644 index 8087e87ec..000000000 --- a/examples/graphql-modules/user/user.module.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { GraphQLModule } from "@graphql-modules/core"; -import * as path from "path"; -import { buildSchemaSync } from "../../../src"; - -import RecipeResolver from "./recipe.resolver"; -import UserResolver from "./user.resolver"; -import UserService from "./user.service"; -import Recipe from "./recipe.type"; - -const resolvers = [RecipeResolver, UserResolver] as const; - -// @ts-ignore -const UserModule = new GraphQLModule({ - providers: [UserService, ...resolvers], - extraSchemas: [ - buildSchemaSync({ - resolvers, - orphanedTypes: [Recipe], - container: ({ context }) => UserModule.injector.getSessionInjector(context), - skipCheck: true, - emitSchemaFile: path.resolve(__dirname, "user-schema.gql"), - }), - ], -}); - -export default UserModule; diff --git a/examples/graphql-modules/user/user.resolver.ts b/examples/graphql-modules/user/user.resolver.ts deleted file mode 100644 index 08f4adaa1..000000000 --- a/examples/graphql-modules/user/user.resolver.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Injectable } from "@graphql-modules/di"; -import { Query, Resolver } from "../../../src"; - -import User from "./user.type"; -import UserService from "./user.service"; - -@Injectable() -@Resolver(of => User) -export default class UserResolver { - constructor(private readonly userService: UserService) {} - - @Query(returns => [User]) - users() { - return this.userService.getAll(); - } -} diff --git a/examples/graphql-modules/user/user.seed.ts b/examples/graphql-modules/user/user.seed.ts deleted file mode 100644 index 33c1e1212..000000000 --- a/examples/graphql-modules/user/user.seed.ts +++ /dev/null @@ -1,18 +0,0 @@ -import User from "./user.type"; - -export default function createUsers(): User[] { - return [ - { - id: 1, - age: 28, - name: "John Doe", - email: "john.doe@typegraphql.com", - }, - { - id: 2, - age: 18, - name: "Ann Smith", - email: "ann.smith@typegraphql.com", - }, - ]; -} diff --git a/examples/graphql-modules/user/user.service.ts b/examples/graphql-modules/user/user.service.ts deleted file mode 100644 index 0389c098a..000000000 --- a/examples/graphql-modules/user/user.service.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Injectable } from "@graphql-modules/di"; - -import User from "./user.type"; -import createUsers from "./user.seed"; - -@Injectable() -export default class UserService { - private readonly users: User[] = createUsers(); - - getAll() { - return this.users; - } - - findById(id: number) { - return this.users.find(it => it.id === id); - } -} diff --git a/examples/graphql-modules/user/user.type.ts b/examples/graphql-modules/user/user.type.ts deleted file mode 100644 index cdd377c61..000000000 --- a/examples/graphql-modules/user/user.type.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { ObjectType, Int, Field } from "../../../src"; - -@ObjectType() -export default class User { - @Field(type => Int) - id: number; - - @Field() - name: string; - - @Field() - email: string; - - @Field(type => Int) - age: number; -} diff --git a/examples/simple-usage/examples.gql b/examples/graphql-scalars/examples.graphql similarity index 76% rename from examples/simple-usage/examples.gql rename to examples/graphql-scalars/examples.graphql index 67e1aed95..35edc9e98 100644 --- a/examples/simple-usage/examples.gql +++ b/examples/graphql-scalars/examples.graphql @@ -19,10 +19,7 @@ query GetRecipes { } mutation AddRecipe { - addRecipe(recipe: { - title: "New recipe" - description: "Simple description" - }) { + addRecipe(recipe: { title: "New recipe", description: "Simple description" }) { creationDate } } diff --git a/examples/graphql-scalars/index.ts b/examples/graphql-scalars/index.ts new file mode 100644 index 000000000..76a69d3f5 --- /dev/null +++ b/examples/graphql-scalars/index.ts @@ -0,0 +1,25 @@ +import "reflect-metadata"; +import path from "node:path"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { buildSchema } from "type-graphql"; +import { RecipeResolver } from "./recipe.resolver"; + +async function bootstrap() { + // Build TypeGraphQL executable schema + const schema = await buildSchema({ + // Array of resolvers + resolvers: [RecipeResolver], + // Create 'schema.graphql' file with schema definition in current directory + emitSchemaFile: path.resolve(__dirname, "schema.graphql"), + }); + + // Create GraphQL server + const server = new ApolloServer({ schema }); + + // Start server + const { url } = await startStandaloneServer(server, { listen: { port: 4000 } }); + console.log(`GraphQL server ready at ${url}`); +} + +bootstrap().catch(console.error); diff --git a/examples/apollo-cache/recipe-samples.ts b/examples/graphql-scalars/recipe.data.ts similarity index 93% rename from examples/apollo-cache/recipe-samples.ts rename to examples/graphql-scalars/recipe.data.ts index 1f0e6419b..e82854f9b 100644 --- a/examples/apollo-cache/recipe-samples.ts +++ b/examples/graphql-scalars/recipe.data.ts @@ -1,28 +1,28 @@ -import { Recipe } from "./recipe-type"; +import { Recipe } from "./recipe.type"; + +function createRecipe(recipeData: Partial) { + return Object.assign(new Recipe(), recipeData); +} export function createRecipeSamples() { return [ createRecipe({ - title: "Recipe 1", description: "Desc 1", + title: "Recipe 1", ratings: [0, 3, 1], creationDate: new Date("2018-04-11"), }), createRecipe({ - title: "Recipe 2", description: "Desc 2", + title: "Recipe 2", ratings: [4, 2, 3, 1], creationDate: new Date("2018-04-15"), }), createRecipe({ - title: "Recipe 3", description: "Desc 3", + title: "Recipe 3", ratings: [5, 4], creationDate: new Date(), }), ]; } - -function createRecipe(recipeData: Partial) { - return Object.assign(new Recipe(), recipeData); -} diff --git a/examples/graphql-scalars/recipe.input.ts b/examples/graphql-scalars/recipe.input.ts new file mode 100644 index 000000000..90bad5910 --- /dev/null +++ b/examples/graphql-scalars/recipe.input.ts @@ -0,0 +1,12 @@ +import { GraphQLNonEmptyString } from "graphql-scalars"; +import { Field, InputType } from "type-graphql"; +import { type Recipe } from "./recipe.type"; + +@InputType() +export class RecipeInput implements Partial { + @Field(_type => GraphQLNonEmptyString) + title!: string; + + @Field(_type => GraphQLNonEmptyString, { nullable: true }) + description?: string; +} diff --git a/examples/graphql-scalars/recipe.resolver.ts b/examples/graphql-scalars/recipe.resolver.ts new file mode 100644 index 000000000..ae3020865 --- /dev/null +++ b/examples/graphql-scalars/recipe.resolver.ts @@ -0,0 +1,50 @@ +import { GraphQLNonNegativeInt } from "graphql-scalars"; +import { + Arg, + FieldResolver, + Int, + Mutation, + Query, + Resolver, + type ResolverInterface, + Root, +} from "type-graphql"; +import { createRecipeSamples } from "./recipe.data"; +import { RecipeInput } from "./recipe.input"; +import { Recipe } from "./recipe.type"; + +@Resolver(_of => Recipe) +export class RecipeResolver implements ResolverInterface { + private readonly items: Recipe[] = createRecipeSamples(); + + @Query(_returns => Recipe, { nullable: true }) + async recipe(@Arg("title") title: string): Promise { + return this.items.find(recipe => recipe.title === title); + } + + @Query(_returns => [Recipe], { description: "Get all the recipes from around the world " }) + async recipes(): Promise { + return this.items; + } + + @Mutation(_returns => Recipe) + async addRecipe(@Arg("recipe") recipeInput: RecipeInput): Promise { + const recipe = Object.assign(new Recipe(), { + description: recipeInput.description, + title: recipeInput.title, + ratings: [], + creationDate: new Date(), + }); + await this.items.push(recipe); + + return recipe; + } + + @FieldResolver(_returns => GraphQLNonNegativeInt) + ratingsCount( + @Root() recipe: Recipe, + @Arg("minRate", _type => Int, { defaultValue: 0 }) minRate: number, + ): number { + return recipe.ratings.filter(rating => rating >= minRate).length; + } +} diff --git a/examples/graphql-scalars/recipe.type.ts b/examples/graphql-scalars/recipe.type.ts new file mode 100644 index 000000000..7c4c98368 --- /dev/null +++ b/examples/graphql-scalars/recipe.type.ts @@ -0,0 +1,47 @@ +import { + GraphQLNonEmptyString, + GraphQLNonNegativeFloat, + GraphQLNonNegativeInt, + GraphQLTimestamp, +} from "graphql-scalars"; +import { Field, ObjectType } from "type-graphql"; + +@ObjectType({ description: "Object representing cooking recipe" }) +export class Recipe { + @Field(_type => GraphQLNonEmptyString) + title!: string; + + @Field(_type => GraphQLNonEmptyString, { + nullable: true, + deprecationReason: "Use 'description' field instead", + }) + get specification(): string | undefined { + return this.description; + } + + @Field(_type => GraphQLNonEmptyString, { + nullable: true, + description: "The recipe description with preparation info", + }) + description?: string; + + @Field(_type => [GraphQLNonNegativeInt]) + ratings!: number[]; + + @Field(_type => GraphQLTimestamp) + creationDate!: Date; + + @Field(_type => GraphQLNonNegativeInt) + ratingsCount!: number; + + @Field(_type => GraphQLNonNegativeFloat, { nullable: true }) + get averageRating(): number | null { + const ratingsCount = this.ratings.length; + if (ratingsCount === 0) { + return null; + } + const ratingsSum = this.ratings.reduce((a, b) => a + b, 0); + + return ratingsSum / ratingsCount; + } +} diff --git a/examples/graphql-scalars/schema.graphql b/examples/graphql-scalars/schema.graphql new file mode 100644 index 000000000..497296327 --- /dev/null +++ b/examples/graphql-scalars/schema.graphql @@ -0,0 +1,59 @@ +# ----------------------------------------------- +# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!! +# !!! DO NOT MODIFY THIS FILE BY YOURSELF !!! +# ----------------------------------------------- + +type Mutation { + addRecipe(recipe: RecipeInput!): Recipe! +} + +""" +A string that cannot be passed as an empty value +""" +scalar NonEmptyString + +""" +Floats that will have a value of 0 or more. +""" +scalar NonNegativeFloat + +""" +Integers that will have a value of 0 or more. +""" +scalar NonNegativeInt + +type Query { + recipe(title: String!): Recipe + + """ + Get all the recipes from around the world + """ + recipes: [Recipe!]! +} + +""" +Object representing cooking recipe +""" +type Recipe { + averageRating: NonNegativeFloat + creationDate: Timestamp! + + """ + The recipe description with preparation info + """ + description: NonEmptyString + ratings: [NonNegativeInt!]! + ratingsCount(minRate: Int! = 0): NonNegativeInt! + specification: NonEmptyString @deprecated(reason: "Use 'description' field instead") + title: NonEmptyString! +} + +input RecipeInput { + description: NonEmptyString + title: NonEmptyString! +} + +""" +The javascript `Date` as integer. Type represents date and time as number of milliseconds from start of UNIX epoch. +""" +scalar Timestamp diff --git a/examples/interfaces-inheritance/employee/employee.input.ts b/examples/interfaces-inheritance/employee/employee.input.ts index 3b20f9246..f8943b30d 100644 --- a/examples/interfaces-inheritance/employee/employee.input.ts +++ b/examples/interfaces-inheritance/employee/employee.input.ts @@ -1,9 +1,8 @@ -import { InputType, Field } from "../../../src"; - -import { PersonInput } from "../person/person.input"; +import { Field, InputType } from "type-graphql"; +import { PersonInput } from "../person"; @InputType() export class EmployeeInput extends PersonInput { @Field() - companyName: string; + companyName!: string; } diff --git a/examples/interfaces-inheritance/employee/employee.type.ts b/examples/interfaces-inheritance/employee/employee.type.ts index efdd49def..c02cfa363 100644 --- a/examples/interfaces-inheritance/employee/employee.type.ts +++ b/examples/interfaces-inheritance/employee/employee.type.ts @@ -1,9 +1,8 @@ -import { Field, ObjectType } from "../../../src"; - -import { Person } from "../person/person.type"; +import { Field, ObjectType } from "type-graphql"; +import { Person } from "../person"; @ObjectType() export class Employee extends Person { @Field() - companyName: string; + companyName!: string; } diff --git a/examples/interfaces-inheritance/employee/index.ts b/examples/interfaces-inheritance/employee/index.ts new file mode 100644 index 000000000..f40284610 --- /dev/null +++ b/examples/interfaces-inheritance/employee/index.ts @@ -0,0 +1,2 @@ +export * from "./employee.input"; +export * from "./employee.type"; diff --git a/examples/interfaces-inheritance/examples.gql b/examples/interfaces-inheritance/examples.graphql similarity index 50% rename from examples/interfaces-inheritance/examples.gql rename to examples/interfaces-inheritance/examples.graphql index 8c520715e..1814957e6 100644 --- a/examples/interfaces-inheritance/examples.gql +++ b/examples/interfaces-inheritance/examples.graphql @@ -14,22 +14,18 @@ query GetPersons { } mutation AddStudent { - addStudent(input: { - name: "Student 1" - dateOfBirth: "1991-11-30T00:00:00.000Z" - universityName: "Uni 1" - }) { + addStudent( + input: { name: "Student 1", dateOfBirth: "1991-11-30T00:00:00.000Z", universityName: "Uni 1" } + ) { id age } } mutation AddEmployee { - addEmployee(input: { - name: "Employee 1" - dateOfBirth: "1995-07-23T00:00:00.000Z" - companyName: "Company 1" - }) { + addEmployee( + input: { name: "Employee 1", dateOfBirth: "1995-07-23T00:00:00.000Z", companyName: "Company 1" } + ) { id age } diff --git a/examples/interfaces-inheritance/helpers.ts b/examples/interfaces-inheritance/helpers.ts index f7f0df3e8..31e3d4792 100644 --- a/examples/interfaces-inheritance/helpers.ts +++ b/examples/interfaces-inheritance/helpers.ts @@ -1,4 +1,4 @@ -import * as crypto from "crypto"; +import crypto from "node:crypto"; export function getId(): string { const randomNumber = Math.random(); @@ -9,6 +9,6 @@ export function getId(): string { export function calculateAge(birthday: Date) { const ageDiffMs = Date.now() - birthday.getTime(); - const ageDate = new Date(ageDiffMs); // miliseconds from epoch + const ageDate = new Date(ageDiffMs); // Milliseconds from epoch return Math.abs(ageDate.getUTCFullYear() - 1970); } diff --git a/examples/interfaces-inheritance/index.ts b/examples/interfaces-inheritance/index.ts index 1dc80385a..983b47567 100644 --- a/examples/interfaces-inheritance/index.ts +++ b/examples/interfaces-inheritance/index.ts @@ -1,27 +1,28 @@ import "reflect-metadata"; -import { ApolloServer } from "apollo-server"; -import * as path from "path"; -import { buildSchema } from "../../src"; - +import path from "node:path"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { buildSchema } from "type-graphql"; +import { Person } from "./person"; import { MultiResolver } from "./resolver"; -import { Person } from "./person/person.type"; async function bootstrap() { - // build TypeGraphQL executable schema + // Build TypeGraphQL executable schema const schema = await buildSchema({ + // Array of resolvers resolvers: [MultiResolver], - emitSchemaFile: path.resolve(__dirname, "schema.gql"), - // provide the type that implements an interface - // but is not directly used in schema + // Create 'schema.graphql' file with schema definition in current directory + emitSchemaFile: path.resolve(__dirname, "schema.graphql"), + // Provide the type that implements an interface but it is not directly used in schema orphanedTypes: [Person], }); // Create GraphQL server const server = new ApolloServer({ schema }); - // Start the server - const { url } = await server.listen(4000); - console.log(`Server is running, GraphQL Playground available at ${url}`); + // Start server + const { url } = await startStandaloneServer(server, { listen: { port: 4000 } }); + console.log(`GraphQL server ready at ${url}`); } -bootstrap(); +bootstrap().catch(console.error); diff --git a/examples/interfaces-inheritance/person/index.ts b/examples/interfaces-inheritance/person/index.ts new file mode 100644 index 000000000..a86bc2298 --- /dev/null +++ b/examples/interfaces-inheritance/person/index.ts @@ -0,0 +1,3 @@ +export * from "./person.input"; +export * from "./person.interface"; +export * from "./person.type"; diff --git a/examples/interfaces-inheritance/person/person.input.ts b/examples/interfaces-inheritance/person/person.input.ts index 52f69f78f..b07f09b45 100644 --- a/examples/interfaces-inheritance/person/person.input.ts +++ b/examples/interfaces-inheritance/person/person.input.ts @@ -1,10 +1,10 @@ -import { InputType, Field } from "../../../src"; +import { Field, InputType } from "type-graphql"; @InputType() export class PersonInput { @Field() - name: string; + name!: string; @Field() - dateOfBirth: Date; + dateOfBirth!: Date; } diff --git a/examples/interfaces-inheritance/person/person.interface.ts b/examples/interfaces-inheritance/person/person.interface.ts index fe54b334a..a611895ca 100644 --- a/examples/interfaces-inheritance/person/person.interface.ts +++ b/examples/interfaces-inheritance/person/person.interface.ts @@ -1,23 +1,22 @@ -import { InterfaceType, Field, Int, ID, Arg } from "../../../src"; - -import { IResource } from "../resource/resource.interface"; +import { Arg, Field, ID, Int, InterfaceType } from "type-graphql"; +import { type IResource } from "../resource"; @InterfaceType({ - // workaround for bug: https://github.com/MichalLytek/type-graphql/issues/373 + // Workaround issue #373 (https://github.com/MichalLytek/type-graphql/issues/373) resolveType: value => value.constructor.name, }) export abstract class IPerson implements IResource { - @Field(type => ID) - id: string; + @Field(_type => ID) + id!: string; @Field() - name: string; + name!: string; - @Field(type => Int) - age: number; + @Field(_type => Int) + age!: number; @Field() - avatar(@Arg("size") size: number): string { + avatar(@Arg("size") _size: number): string { throw new Error("Method not implemented."); } } diff --git a/examples/interfaces-inheritance/person/person.type.ts b/examples/interfaces-inheritance/person/person.type.ts index c38eba7a3..6a4211d0f 100644 --- a/examples/interfaces-inheritance/person/person.type.ts +++ b/examples/interfaces-inheritance/person/person.type.ts @@ -1,12 +1,13 @@ -import { ObjectType, Field, Arg } from "../../../src"; - +import { Arg, Field, ObjectType } from "type-graphql"; import { IPerson } from "./person.interface"; @ObjectType({ implements: IPerson }) export class Person implements IPerson { - id: string; - name: string; - age: number; + id!: string; + + name!: string; + + age!: number; @Field() avatar(@Arg("size") size: number): string { diff --git a/examples/interfaces-inheritance/resolver.ts b/examples/interfaces-inheritance/resolver.ts index 02aa939a0..db7d5cbec 100644 --- a/examples/interfaces-inheritance/resolver.ts +++ b/examples/interfaces-inheritance/resolver.ts @@ -1,26 +1,23 @@ -import { Resolver, Query, Arg, Mutation } from "../../src"; - -import { getId, calculateAge } from "./helpers"; -import { Student } from "./student/student.type"; -import { Employee } from "./employee/employee.type"; -import { StudentInput } from "./student/student.input"; -import { EmployeeInput } from "./employee/employee.input"; -import { IPerson } from "./person/person.interface"; +import { Arg, Mutation, Query, Resolver } from "type-graphql"; +import { Employee, EmployeeInput } from "./employee"; +import { calculateAge, getId } from "./helpers"; +import { IPerson } from "./person"; +import { Student, StudentInput } from "./student"; @Resolver() export class MultiResolver { private readonly personsRegistry: IPerson[] = []; - @Query(returns => [IPerson]) + @Query(_returns => [IPerson]) persons(): IPerson[] { - // this one returns interfaces - // so GraphQL has to be able to resolve type of the item + // This one returns interfaces, + // GraphQL has to be able to resolve type of the item return this.personsRegistry; } @Mutation() addStudent(@Arg("input") input: StudentInput): Student { - // be sure to create real instances of classes + // Be sure to create real instances of classes const student = Object.assign(new Student(), { id: getId(), name: input.name, diff --git a/examples/interfaces-inheritance/resource/index.ts b/examples/interfaces-inheritance/resource/index.ts new file mode 100644 index 000000000..2b17916ac --- /dev/null +++ b/examples/interfaces-inheritance/resource/index.ts @@ -0,0 +1 @@ +export * from "./resource.interface"; diff --git a/examples/interfaces-inheritance/resource/resource.interface.ts b/examples/interfaces-inheritance/resource/resource.interface.ts index ceda50db9..45283e1c6 100644 --- a/examples/interfaces-inheritance/resource/resource.interface.ts +++ b/examples/interfaces-inheritance/resource/resource.interface.ts @@ -1,7 +1,7 @@ -import { InterfaceType, ID, Field } from "../../../src"; +import { Field, ID, InterfaceType } from "type-graphql"; @InterfaceType() export abstract class IResource { - @Field(type => ID) - id: string; + @Field(_type => ID) + id!: string; } diff --git a/examples/interfaces-inheritance/schema.gql b/examples/interfaces-inheritance/schema.graphql similarity index 60% rename from examples/interfaces-inheritance/schema.gql rename to examples/interfaces-inheritance/schema.graphql index 5b7e641c8..b9218b871 100644 --- a/examples/interfaces-inheritance/schema.gql +++ b/examples/interfaces-inheritance/schema.graphql @@ -4,12 +4,13 @@ # ----------------------------------------------- """ -The javascript `Date` as string. Type represents date and time as the ISO Date string. +A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar.This scalar is serialized to a string in ISO 8601 format and parsed from a string in ISO 8601 format. """ -scalar DateTime +scalar DateTimeISO type Employee implements IPerson { age: Int! + avatar(size: Float!): String! companyName: String! id: ID! name: String! @@ -17,12 +18,13 @@ type Employee implements IPerson { input EmployeeInput { companyName: String! - dateOfBirth: DateTime! + dateOfBirth: DateTimeISO! name: String! } interface IPerson { age: Int! + avatar(size: Float!): String! id: ID! name: String! } @@ -34,6 +36,7 @@ type Mutation { type Person implements IPerson { age: Int! + avatar(size: Float!): String! id: ID! name: String! } @@ -44,13 +47,14 @@ type Query { type Student implements IPerson { age: Int! + avatar(size: Float!): String! id: ID! name: String! universityName: String! } input StudentInput { - dateOfBirth: DateTime! + dateOfBirth: DateTimeISO! name: String! universityName: String! } diff --git a/examples/interfaces-inheritance/student/index.ts b/examples/interfaces-inheritance/student/index.ts new file mode 100644 index 000000000..51b83a03c --- /dev/null +++ b/examples/interfaces-inheritance/student/index.ts @@ -0,0 +1,2 @@ +export * from "./student.input"; +export * from "./student.type"; diff --git a/examples/interfaces-inheritance/student/student.input.ts b/examples/interfaces-inheritance/student/student.input.ts index 696460b1e..eee690b87 100644 --- a/examples/interfaces-inheritance/student/student.input.ts +++ b/examples/interfaces-inheritance/student/student.input.ts @@ -1,9 +1,8 @@ -import { InputType, Field } from "../../../src"; - -import { PersonInput } from "../person/person.input"; +import { Field, InputType } from "type-graphql"; +import { PersonInput } from "../person"; @InputType() export class StudentInput extends PersonInput { @Field() - universityName: string; + universityName!: string; } diff --git a/examples/interfaces-inheritance/student/student.type.ts b/examples/interfaces-inheritance/student/student.type.ts index 999d46b8a..aa1c01e00 100644 --- a/examples/interfaces-inheritance/student/student.type.ts +++ b/examples/interfaces-inheritance/student/student.type.ts @@ -1,9 +1,8 @@ -import { Field, ObjectType } from "../../../src"; - -import { Person } from "../person/person.type"; +import { Field, ObjectType } from "type-graphql"; +import { Person } from "../person"; @ObjectType() export class Student extends Person { @Field() - universityName: string; + universityName!: string; } diff --git a/examples/middlewares-custom-decorators/context.ts b/examples/middlewares-custom-decorators/context.type.ts similarity index 55% rename from examples/middlewares-custom-decorators/context.ts rename to examples/middlewares-custom-decorators/context.type.ts index c0783dd95..b2c965388 100644 --- a/examples/middlewares-custom-decorators/context.ts +++ b/examples/middlewares-custom-decorators/context.type.ts @@ -1,4 +1,4 @@ -import User from "./user"; +import { type User } from "./user.type"; export interface Context { currentUser: User; diff --git a/examples/middlewares-custom-decorators/decorators/current-user.ts b/examples/middlewares-custom-decorators/decorators/current-user.ts index 1549b96ea..75f1b0443 100644 --- a/examples/middlewares-custom-decorators/decorators/current-user.ts +++ b/examples/middlewares-custom-decorators/decorators/current-user.ts @@ -1,6 +1,6 @@ -import { createParamDecorator } from "../../../src"; -import { Context } from "../context"; +import { createParamDecorator } from "type-graphql"; +import { type Context } from "../context.type"; -export default function CurrentUser() { +export function CurrentUser() { return createParamDecorator(({ context }) => context.currentUser); } diff --git a/examples/middlewares-custom-decorators/decorators/index.ts b/examples/middlewares-custom-decorators/decorators/index.ts new file mode 100644 index 000000000..567475a68 --- /dev/null +++ b/examples/middlewares-custom-decorators/decorators/index.ts @@ -0,0 +1,2 @@ +export * from "./current-user"; +export * from "./validate-args"; diff --git a/examples/middlewares-custom-decorators/decorators/validate-args.ts b/examples/middlewares-custom-decorators/decorators/validate-args.ts index 9b1c4aeff..2f5100473 100644 --- a/examples/middlewares-custom-decorators/decorators/validate-args.ts +++ b/examples/middlewares-custom-decorators/decorators/validate-args.ts @@ -1,8 +1,8 @@ import { validate } from "class-validator"; -import { ClassType, ArgumentValidationError, createMethodDecorator } from "../../../src"; +import { ArgumentValidationError, type ClassType, createMethodDecorator } from "type-graphql"; -// sample implementation of custom validation decorator -// this example use `class-validator` however you can plug-in `joi` or any other lib +// Sample implementation of custom validation decorator +// This example use 'class-validator' however you can plug-in 'joi' or any other validation library export function ValidateArgs(Type: ClassType) { return createMethodDecorator(async ({ args }, next) => { const instance = Object.assign(new Type(), args); diff --git a/examples/middlewares-custom-decorators/examples.gql b/examples/middlewares-custom-decorators/examples.graphql similarity index 91% rename from examples/middlewares-custom-decorators/examples.gql rename to examples/middlewares-custom-decorators/examples.graphql index e8b77cdf4..ee29ea8dd 100644 --- a/examples/middlewares-custom-decorators/examples.gql +++ b/examples/middlewares-custom-decorators/examples.graphql @@ -5,7 +5,7 @@ query InvalidArgs { } } -query LogginQuery { +query LoggingQuery { recipes { title description diff --git a/examples/middlewares-custom-decorators/index.ts b/examples/middlewares-custom-decorators/index.ts index 3f5f65f32..fdae32f0f 100644 --- a/examples/middlewares-custom-decorators/index.ts +++ b/examples/middlewares-custom-decorators/index.ts @@ -1,38 +1,42 @@ import "reflect-metadata"; +import path from "node:path"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { buildSchema } from "type-graphql"; import Container from "typedi"; -import { ApolloServer } from "apollo-server"; -import { buildSchema } from "../../src"; - -import { RecipeResolver } from "./recipe/recipe.resolver"; -import { ResolveTimeMiddleware } from "./middlewares/resolve-time"; -import { ErrorLoggerMiddleware } from "./middlewares/error-logger"; -import { Context } from "./context"; +import { type Context } from "./context.type"; +import { ErrorLoggerMiddleware, ResolveTimeMiddleware } from "./middlewares"; +import { RecipeResolver } from "./recipe"; async function bootstrap() { - // build TypeGraphQL executable schema + // Build TypeGraphQL executable schema const schema = await buildSchema({ + // Array of resolvers resolvers: [RecipeResolver], + // Array of global middlewares globalMiddlewares: [ErrorLoggerMiddleware, ResolveTimeMiddleware], + // Create 'schema.graphql' file with schema definition in current directory + emitSchemaFile: path.resolve(__dirname, "schema.graphql"), + // Registry 3rd party IOC container container: Container, }); // Create GraphQL server - const server = new ApolloServer({ - schema, - context: (): Context => { - return { - // example user - currentUser: { - id: 123, - name: "Sample user", - }, - }; - }, - }); + const server = new ApolloServer({ schema }); - // Start the server - const { url } = await server.listen(4000); - console.log(`Server is running, GraphQL Playground available at ${url}`); + // Start server + const { url } = await startStandaloneServer(server, { + listen: { port: 4000 }, + // Provide context for each request + context: async (): Promise => ({ + // Create mocked user in context + currentUser: { + id: 123, + name: "Sample user", + }, + }), + }); + console.log(`GraphQL server ready at ${url}`); } -bootstrap(); +bootstrap().catch(console.error); diff --git a/examples/middlewares-custom-decorators/logger.ts b/examples/middlewares-custom-decorators/logger.ts index 8b7623a7b..ef6daba13 100644 --- a/examples/middlewares-custom-decorators/logger.ts +++ b/examples/middlewares-custom-decorators/logger.ts @@ -3,7 +3,7 @@ import { Service } from "typedi"; @Service() export class Logger { log(...args: any[]) { - // replace with more sophisticated solution :) + // Replace with a more sophisticated solution console.log(...args); } } diff --git a/examples/middlewares-custom-decorators/middlewares/error-logger.ts b/examples/middlewares-custom-decorators/middlewares/error-logger.ts index 4b9ef0e2b..df8cd3deb 100644 --- a/examples/middlewares-custom-decorators/middlewares/error-logger.ts +++ b/examples/middlewares-custom-decorators/middlewares/error-logger.ts @@ -1,7 +1,11 @@ +import { + ArgumentValidationError, + type MiddlewareInterface, + type NextFn, + type ResolverData, +} from "type-graphql"; import { Service } from "typedi"; -import { MiddlewareInterface, NextFn, ResolverData, ArgumentValidationError } from "../../../src"; - -import { Context } from "../context"; +import { type Context } from "../context.type"; import { Logger } from "../logger"; @Service() @@ -13,13 +17,13 @@ export class ErrorLoggerMiddleware implements MiddlewareInterface { return await next(); } catch (err) { this.logger.log({ - message: err.message, + message: (err as Error).message, operation: info.operation.operation, fieldName: info.fieldName, userName: context.currentUser.name, }); if (!(err instanceof ArgumentValidationError)) { - // hide errors from db like printing sql query + // Hide errors from db like printing sql query throw new Error("Unknown error occurred. Try again later!"); } throw err; diff --git a/examples/middlewares-custom-decorators/middlewares/index.ts b/examples/middlewares-custom-decorators/middlewares/index.ts new file mode 100644 index 000000000..8f38d19b3 --- /dev/null +++ b/examples/middlewares-custom-decorators/middlewares/index.ts @@ -0,0 +1,4 @@ +export * from "./error-logger"; +export * from "./log-access"; +export * from "./number-interceptor"; +export * from "./resolve-time"; diff --git a/examples/middlewares-custom-decorators/middlewares/log-access.ts b/examples/middlewares-custom-decorators/middlewares/log-access.ts index 7f6e4aed6..6a382bc5f 100644 --- a/examples/middlewares-custom-decorators/middlewares/log-access.ts +++ b/examples/middlewares-custom-decorators/middlewares/log-access.ts @@ -1,7 +1,6 @@ +import { type MiddlewareInterface, type NextFn, type ResolverData } from "type-graphql"; import { Service } from "typedi"; -import { MiddlewareInterface, NextFn, ResolverData } from "../../../src"; - -import { Context } from "../context"; +import { type Context } from "../context.type"; import { Logger } from "../logger"; @Service() diff --git a/examples/middlewares-custom-decorators/middlewares/number-interceptor.ts b/examples/middlewares-custom-decorators/middlewares/number-interceptor.ts index c9e386d9d..6b0317f5d 100644 --- a/examples/middlewares-custom-decorators/middlewares/number-interceptor.ts +++ b/examples/middlewares-custom-decorators/middlewares/number-interceptor.ts @@ -1,9 +1,9 @@ -import { MiddlewareFn } from "../../../src"; +import { type MiddlewareFn } from "type-graphql"; export function NumberInterceptor(minValue: number): MiddlewareFn { return async (_, next) => { const result = await next(); - // hide ratings below minValue + // Hide ratings below minValue if (typeof result === "number" && result < minValue) { return null; } diff --git a/examples/middlewares-custom-decorators/middlewares/resolve-time.ts b/examples/middlewares-custom-decorators/middlewares/resolve-time.ts index 4ebd10237..105e4c956 100644 --- a/examples/middlewares-custom-decorators/middlewares/resolve-time.ts +++ b/examples/middlewares-custom-decorators/middlewares/resolve-time.ts @@ -1,4 +1,4 @@ -import { MiddlewareFn } from "../../../src"; +import { type MiddlewareFn } from "type-graphql"; export const ResolveTimeMiddleware: MiddlewareFn = async ({ info }, next) => { const start = Date.now(); diff --git a/examples/middlewares-custom-decorators/recipe/index.ts b/examples/middlewares-custom-decorators/recipe/index.ts new file mode 100644 index 000000000..1fdd9f11e --- /dev/null +++ b/examples/middlewares-custom-decorators/recipe/index.ts @@ -0,0 +1,4 @@ +export * from "./recipe.args"; +export * from "./recipe.resolver"; +export * from "./recipe.data"; +export * from "./recipe.type"; diff --git a/examples/middlewares-custom-decorators/recipe/recipe.args.ts b/examples/middlewares-custom-decorators/recipe/recipe.args.ts index 7ee59e943..23a438097 100644 --- a/examples/middlewares-custom-decorators/recipe/recipe.args.ts +++ b/examples/middlewares-custom-decorators/recipe/recipe.args.ts @@ -1,14 +1,14 @@ -import { IsPositive, Max, Min } from "class-validator"; -import { ArgsType, Field, Int } from "../../../src"; +import { Max, Min } from "class-validator"; +import { ArgsType, Field, Int } from "type-graphql"; @ArgsType() export class RecipesArgs { - @Field(type => Int) + @Field(_type => Int) @Min(0) - skip: number = 0; + skip = 0; - @Field(type => Int) + @Field(_type => Int) @Min(1) @Max(50) - take: number = 10; + take = 10; } diff --git a/examples/middlewares-custom-decorators/recipe/recipe.samples.ts b/examples/middlewares-custom-decorators/recipe/recipe.data.ts similarity index 94% rename from examples/middlewares-custom-decorators/recipe/recipe.samples.ts rename to examples/middlewares-custom-decorators/recipe/recipe.data.ts index 4aeb1f891..fd4725634 100644 --- a/examples/middlewares-custom-decorators/recipe/recipe.samples.ts +++ b/examples/middlewares-custom-decorators/recipe/recipe.data.ts @@ -1,6 +1,10 @@ import { Recipe } from "./recipe.type"; -export default [ +function createRecipe(recipeData: Partial): Recipe { + return Object.assign(new Recipe(), recipeData); +} + +export const recipes = [ createRecipe({ description: "Desc 1", title: "Recipe 1", @@ -17,7 +21,3 @@ export default [ ratings: [4, 5, 3, 1, 5], }), ]; - -function createRecipe(recipeData: Partial): Recipe { - return Object.assign(new Recipe(), recipeData); -} diff --git a/examples/middlewares-custom-decorators/recipe/recipe.resolver.ts b/examples/middlewares-custom-decorators/recipe/recipe.resolver.ts index f11803ab0..242ce38f2 100644 --- a/examples/middlewares-custom-decorators/recipe/recipe.resolver.ts +++ b/examples/middlewares-custom-decorators/recipe/recipe.resolver.ts @@ -1,26 +1,26 @@ -import { Resolver, Query, Args } from "../../../src"; - -import recipeSamples from "./recipe.samples"; -import { Recipe } from "./recipe.type"; +import { Args, Query, Resolver } from "type-graphql"; +import { Service } from "typedi"; import { RecipesArgs } from "./recipe.args"; -import { ValidateArgs } from "../decorators/validate-args"; -import CurrentUser from "../decorators/current-user"; -import User from "../user"; +import { recipes as recipesData } from "./recipe.data"; +import { Recipe } from "./recipe.type"; +import { CurrentUser, ValidateArgs } from "../decorators"; +import { User } from "../user.type"; -@Resolver(of => Recipe) +@Service() +@Resolver(_of => Recipe) export class RecipeResolver { - private readonly items: Recipe[] = recipeSamples; + private readonly items: Recipe[] = recipesData; - @Query(returns => [Recipe]) + @Query(_returns => [Recipe]) @ValidateArgs(RecipesArgs) async recipes( - @Args({ validate: false }) // disable built-in validation here + @Args({ validate: false }) // Disable built-in validation here options: RecipesArgs, @CurrentUser() currentUser: User, ): Promise { console.log(`User "${currentUser.name}" queried for recipes!`); const start = options.skip; const end = options.skip + options.take; - return await this.items.slice(start, end); + return this.items.slice(start, end); } } diff --git a/examples/middlewares-custom-decorators/recipe/recipe.type.ts b/examples/middlewares-custom-decorators/recipe/recipe.type.ts index 16b0a5275..36675dfe3 100644 --- a/examples/middlewares-custom-decorators/recipe/recipe.type.ts +++ b/examples/middlewares-custom-decorators/recipe/recipe.type.ts @@ -1,21 +1,19 @@ -import { Field, ID, ObjectType, Int, Float, UseMiddleware } from "../../../src"; - -import { LogAccessMiddleware } from "../middlewares/log-access"; -import { NumberInterceptor } from "../middlewares/number-interceptor"; +import { Field, Float, Int, ObjectType, UseMiddleware } from "type-graphql"; +import { LogAccessMiddleware, NumberInterceptor } from "../middlewares"; @ObjectType() export class Recipe { @Field() - title: string; + title!: string; @Field({ nullable: true }) description?: string; - @Field(type => [Int]) + @Field(_type => [Int]) @UseMiddleware(LogAccessMiddleware) - ratings: number[]; + ratings!: number[]; - @Field(type => Float, { nullable: true }) + @Field(_type => Float, { nullable: true }) @UseMiddleware(NumberInterceptor(3)) get averageRating(): number | null { const ratingsCount = this.ratings.length; diff --git a/examples/middlewares-custom-decorators/schema.graphql b/examples/middlewares-custom-decorators/schema.graphql new file mode 100644 index 000000000..942016b27 --- /dev/null +++ b/examples/middlewares-custom-decorators/schema.graphql @@ -0,0 +1,15 @@ +# ----------------------------------------------- +# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!! +# !!! DO NOT MODIFY THIS FILE BY YOURSELF !!! +# ----------------------------------------------- + +type Query { + recipes(skip: Int! = 0, take: Int! = 10): [Recipe!]! +} + +type Recipe { + averageRating: Float + description: String + ratings: [Int!]! + title: String! +} diff --git a/examples/middlewares-custom-decorators/user.ts b/examples/middlewares-custom-decorators/user.type.ts similarity index 50% rename from examples/middlewares-custom-decorators/user.ts rename to examples/middlewares-custom-decorators/user.type.ts index 4852b6b00..4a77c7871 100644 --- a/examples/middlewares-custom-decorators/user.ts +++ b/examples/middlewares-custom-decorators/user.type.ts @@ -1,4 +1,4 @@ -export default interface User { +export interface User { id: number; name: string; } diff --git a/examples/mikro-orm/.env.example b/examples/mikro-orm/.env.example new file mode 100644 index 000000000..562af796b --- /dev/null +++ b/examples/mikro-orm/.env.example @@ -0,0 +1 @@ +DATABASE_URL='postgresql://username:password@localhost:5432/type-graphql-example-mikroorm' diff --git a/examples/mikro-orm/context.type.ts b/examples/mikro-orm/context.type.ts new file mode 100644 index 000000000..e6418be01 --- /dev/null +++ b/examples/mikro-orm/context.type.ts @@ -0,0 +1,7 @@ +import { type EntityManager } from "@mikro-orm/core"; +import { type User } from "./entities"; + +export interface Context { + entityManager: EntityManager; + user: User; +} diff --git a/examples/mikro-orm/entities/index.ts b/examples/mikro-orm/entities/index.ts new file mode 100644 index 000000000..435b52abf --- /dev/null +++ b/examples/mikro-orm/entities/index.ts @@ -0,0 +1,3 @@ +export * from "./rating"; +export * from "./recipe"; +export * from "./user"; diff --git a/examples/mikro-orm/entities/rate.ts b/examples/mikro-orm/entities/rate.ts deleted file mode 100644 index 7cf60d5c3..000000000 --- a/examples/mikro-orm/entities/rate.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Entity, Property, ManyToOne, PrimaryKey } from "@mikro-orm/core"; -import { ObjectType, Field, Int } from "../../../src"; - -import { User } from "./user"; -import { Recipe } from "./recipe"; - -@Entity() -@ObjectType() -export class Rate { - @PrimaryKey() - readonly id: number; - - @Field(type => Int) - @Property({ type: "smallint" }) - value: number; - - @Field(type => User) - @ManyToOne(type => User) - user: User; - - @Field() - @Property({ onCreate: () => new Date() }) - date: Date; - - @ManyToOne(type => Recipe) - recipe: Recipe; -} diff --git a/examples/mikro-orm/entities/rating.ts b/examples/mikro-orm/entities/rating.ts new file mode 100644 index 000000000..7b8eafdea --- /dev/null +++ b/examples/mikro-orm/entities/rating.ts @@ -0,0 +1,28 @@ +import { Entity, ManyToOne, OptionalProps, PrimaryKey, Property } from "@mikro-orm/core"; +import { Field, Int, ObjectType } from "type-graphql"; +import { Recipe } from "./recipe"; +import { User } from "./user"; + +@Entity() +@ObjectType() +export class Rating { + @PrimaryKey() + readonly id!: number; + + @Field(_type => Int) + @Property({ type: "smallint" }) + value!: number; + + @Field(_type => User) + @ManyToOne(_type => User) + user!: User; + + @Field() + @Property({ onCreate: () => new Date() }) + date!: Date; + + @ManyToOne(_type => Recipe) + recipe!: Recipe; + + [OptionalProps]?: "date"; +} diff --git a/examples/mikro-orm/entities/recipe.ts b/examples/mikro-orm/entities/recipe.ts index 975a603c8..95ce66e3d 100644 --- a/examples/mikro-orm/entities/recipe.ts +++ b/examples/mikro-orm/entities/recipe.ts @@ -1,29 +1,28 @@ -import { PrimaryKey, Property, ManyToOne, OneToMany, Collection, Entity } from "@mikro-orm/core"; -import { Field, ID, ObjectType } from "../../../src"; - -import { Rate } from "./rate"; +import { Collection, Entity, ManyToOne, OneToMany, PrimaryKey, Property } from "@mikro-orm/core"; +import { Field, ID, ObjectType } from "type-graphql"; +import { Rating } from "./rating"; import { User } from "./user"; @Entity() @ObjectType() export class Recipe { - @Field(type => ID) + @Field(_type => ID) @PrimaryKey() - readonly id: number; + readonly id!: number; @Field() @Property() - title: string; + title!: string; @Field({ nullable: true }) @Property({ nullable: true }) description?: string; - @Field(type => [Rate]) - @OneToMany(type => Rate, rate => rate.recipe) - ratings = new Collection(this); + @Field(_type => [Rating]) + @OneToMany(_type => Rating, rating => rating.recipe) + ratings = new Collection(this); - @Field(type => User) - @ManyToOne(type => User) - author: User; + @Field(_type => User) + @ManyToOne(_type => User) + author!: User; } diff --git a/examples/mikro-orm/entities/user.ts b/examples/mikro-orm/entities/user.ts index 69a1d71f5..8074c3410 100644 --- a/examples/mikro-orm/entities/user.ts +++ b/examples/mikro-orm/entities/user.ts @@ -1,21 +1,21 @@ -import { PrimaryKey, Property, Entity } from "@mikro-orm/core"; -import { Field, ID, ObjectType } from "../../../src"; +import { Entity, PrimaryKey, Property } from "@mikro-orm/core"; +import { Field, ID, ObjectType } from "type-graphql"; @ObjectType() @Entity() export class User { - @Field(type => ID) + @Field(_type => ID) @PrimaryKey() - readonly id: number; + readonly id!: number; @Field() @Property() - email: string; + email!: string; @Field({ nullable: true }) @Property({ nullable: true }) nickname?: string; @Property() - password: string; + password!: string; } diff --git a/examples/typeorm-basic-usage/examples.gql b/examples/mikro-orm/examples.graphql similarity index 79% rename from examples/typeorm-basic-usage/examples.gql rename to examples/mikro-orm/examples.graphql index 424e0bc4a..417a71bca 100644 --- a/examples/typeorm-basic-usage/examples.gql +++ b/examples/mikro-orm/examples.graphql @@ -31,9 +31,7 @@ query GetRecipe { } mutation AddRecipe { - addRecipe(recipe: { - title: "New Recipe" - }) { + addRecipe(recipe: { title: "New Recipe" }) { id ratings { value @@ -44,11 +42,8 @@ mutation AddRecipe { } } -mutation RateRecipe { - rate(rate: { - recipeId: 3 - value: 4 - }) { +mutation RatingRecipe { + rating(rating: { recipeId: 3, value: 4 }) { id ratings { value diff --git a/examples/mikro-orm/helpers.ts b/examples/mikro-orm/helpers.ts index 94e9c5bad..0c1782043 100644 --- a/examples/mikro-orm/helpers.ts +++ b/examples/mikro-orm/helpers.ts @@ -1,13 +1,10 @@ -import { EntityManager } from "@mikro-orm/core"; - -import { Recipe } from "./entities/recipe"; -import { Rate } from "./entities/rate"; -import { User } from "./entities/user"; +import { type EntityManager } from "@mikro-orm/core"; +import { Rating, Recipe, User } from "./entities"; export async function seedDatabase(em: EntityManager) { const defaultUser = em.create(User, { - email: "test@github.com", - nickname: "MichalLytek", + email: "admin@github.com", + nickname: "administrator", password: "s3cr3tp4ssw0rd", }); em.persist(defaultUser); @@ -18,11 +15,11 @@ export async function seedDatabase(em: EntityManager) { author: defaultUser, }); recipe1.ratings.add( - em.create(Rate, { value: 2, user: defaultUser }), - em.create(Rate, { value: 4, user: defaultUser }), - em.create(Rate, { value: 5, user: defaultUser }), - em.create(Rate, { value: 3, user: defaultUser }), - em.create(Rate, { value: 4, user: defaultUser }), + em.create(Rating, { value: 2, user: defaultUser, recipe: recipe1 }), + em.create(Rating, { value: 4, user: defaultUser, recipe: recipe1 }), + em.create(Rating, { value: 5, user: defaultUser, recipe: recipe1 }), + em.create(Rating, { value: 3, user: defaultUser, recipe: recipe1 }), + em.create(Rating, { value: 4, user: defaultUser, recipe: recipe1 }), ); em.persist(recipe1); @@ -31,8 +28,8 @@ export async function seedDatabase(em: EntityManager) { author: defaultUser, }); recipe2.ratings.add( - em.create(Rate, { value: 2, user: defaultUser }), - em.create(Rate, { value: 4, user: defaultUser }), + em.create(Rating, { value: 2, user: defaultUser, recipe: recipe2 }), + em.create(Rating, { value: 4, user: defaultUser, recipe: recipe2 }), ); em.persist(recipe2); diff --git a/examples/mikro-orm/index.ts b/examples/mikro-orm/index.ts index 014c39d6e..4b7a0d722 100644 --- a/examples/mikro-orm/index.ts +++ b/examples/mikro-orm/index.ts @@ -1,60 +1,58 @@ import "reflect-metadata"; -import { ApolloServer } from "apollo-server"; -import * as path from "path"; +import "dotenv/config"; +import path from "node:path"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; import { MikroORM, ReflectMetadataProvider } from "@mikro-orm/core"; -import { buildSchema } from "../../src"; - -import { RecipeResolver } from "./resolvers/recipe-resolver"; -import { RateResolver } from "./resolvers/rate-resolver"; -import { Rate } from "./entities/rate"; -import { Recipe } from "./entities/recipe"; -import { User } from "./entities/user"; -import { ContextType } from "./types"; +import { PostgreSqlDriver } from "@mikro-orm/postgresql"; +import { buildSchema } from "type-graphql"; +import { type Context } from "./context.type"; +import { Rating, Recipe, User } from "./entities"; import { seedDatabase } from "./helpers"; +import { RatingResolver, RecipeResolver } from "./resolvers"; async function bootstrap() { - console.log(`Initializing database connection...`); - const orm = await MikroORM.init({ + // Initialize MikroORM + const orm = await MikroORM.init({ + driver: PostgreSqlDriver, + clientUrl: process.env.DATABASE_URL, + entities: [Rating, Recipe, User], metadataProvider: ReflectMetadataProvider, - cache: { enabled: false }, - entities: [Rate, Recipe, User], - dbName: "mikro-orm", - type: "postgresql", - user: "postgres", // fill this with your username - password: "qwerty", // and password - host: "localhost", // and host - port: 5434, // and port - // baseDir: __dirname, // defaults to `process.cwd()` + metadataCache: { enabled: false }, }); - - console.log(`Setting up the database...`); const generator = orm.getSchemaGenerator(); - // remember to create database manually before launching the code await generator.dropSchema(); await generator.createSchema(); await generator.updateSchema(); - // seed database with some data - const { defaultUser } = await seedDatabase(orm.em); - console.log(`Bootstraping schema and server...`); + // Seed database with some data + const { defaultUser } = await seedDatabase(orm.em.fork()); + + // Build TypeGraphQL executable schema const schema = await buildSchema({ - resolvers: [RecipeResolver, RateResolver], - emitSchemaFile: path.resolve(__dirname, "schema.gql"), + // Array of resolvers + resolvers: [RecipeResolver, RatingResolver], + // Create 'schema.graphql' file with schema definition in current directory + emitSchemaFile: path.resolve(__dirname, "schema.graphql"), validate: false, }); - const server = new ApolloServer({ + + // Create GraphQL server + const server = new ApolloServer({ schema, - playground: true, - context: (): ContextType => ({ - user: defaultUser, - // create fresh instance of entity manager per request - // https://mikro-orm.io/docs/identity-map - entityManager: orm.em.fork(), - }), }); - const { url } = await server.listen(4000); - console.log(`Server is running, GraphQL Playground available at ${url}`); + // Start server + const { url } = await startStandaloneServer(server, { + listen: { port: 4000 }, + context: async () => + ({ + user: defaultUser, + // Create fresh instance of entity manager per request + entityManager: orm.em.fork(), + }) satisfies Context, + }); + console.log(`GraphQL server ready at ${url}`); } bootstrap().catch(console.error); diff --git a/examples/mikro-orm/resolvers/index.ts b/examples/mikro-orm/resolvers/index.ts new file mode 100644 index 000000000..37d003dee --- /dev/null +++ b/examples/mikro-orm/resolvers/index.ts @@ -0,0 +1,2 @@ +export * from "./rating.resolver"; +export * from "./recipe.resolver"; diff --git a/examples/mikro-orm/resolvers/inputs/rate-input.ts b/examples/mikro-orm/resolvers/inputs/rate-input.ts deleted file mode 100644 index 05ea0212f..000000000 --- a/examples/mikro-orm/resolvers/inputs/rate-input.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { InputType, Field, Int } from "../../../../src"; - -@InputType() -export class RateInput { - @Field(type => Int) - recipeId: number; - - @Field(type => Int) - value: number; -} diff --git a/examples/mikro-orm/resolvers/rate-resolver.ts b/examples/mikro-orm/resolvers/rate-resolver.ts deleted file mode 100644 index c518dd32d..000000000 --- a/examples/mikro-orm/resolvers/rate-resolver.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Resolver, FieldResolver, Root, Ctx } from "../../../src"; - -import { Rate } from "../entities/rate"; -import { User } from "../entities/user"; -import { ContextType } from "../types"; - -@Resolver(of => Rate) -export class RateResolver { - @FieldResolver() - async user(@Root() rate: Rate, @Ctx() { entityManager }: ContextType): Promise { - return entityManager.findOneOrFail(User, rate.user.id); - } -} diff --git a/examples/mikro-orm/resolvers/rating.resolver.ts b/examples/mikro-orm/resolvers/rating.resolver.ts new file mode 100644 index 000000000..683160c80 --- /dev/null +++ b/examples/mikro-orm/resolvers/rating.resolver.ts @@ -0,0 +1,11 @@ +import { Ctx, FieldResolver, Resolver, Root } from "type-graphql"; +import { Context } from "../context.type"; +import { Rating, User } from "../entities"; + +@Resolver(_of => Rating) +export class RatingResolver { + @FieldResolver() + async user(@Root() rating: Rating, @Ctx() { entityManager }: Context): Promise { + return entityManager.findOneOrFail(User, rating.user.id); + } +} diff --git a/examples/mikro-orm/resolvers/recipe-resolver.ts b/examples/mikro-orm/resolvers/recipe.resolver.ts similarity index 50% rename from examples/mikro-orm/resolvers/recipe-resolver.ts rename to examples/mikro-orm/resolvers/recipe.resolver.ts index b64c774d0..c93b9a414 100644 --- a/examples/mikro-orm/resolvers/recipe-resolver.ts +++ b/examples/mikro-orm/resolvers/recipe.resolver.ts @@ -1,28 +1,24 @@ -import { Resolver, Query, FieldResolver, Arg, Root, Mutation, Ctx, Int } from "../../../src"; +import { Arg, Ctx, FieldResolver, Int, Mutation, Query, Resolver, Root } from "type-graphql"; +import { RatingInput, RecipeInput } from "./types"; +import { Context } from "../context.type"; +import { Rating, Recipe, User } from "../entities"; -import { Recipe } from "../entities/recipe"; -import { Rate } from "../entities/rate"; -import { User } from "../entities/user"; -import { RecipeInput } from "./inputs/recipe-input"; -import { RateInput } from "./inputs/rate-input"; -import { ContextType } from "../types"; - -@Resolver(of => Recipe) +@Resolver(_of => Recipe) export class RecipeResolver { - @Query(returns => Recipe, { nullable: true }) - recipe(@Arg("recipeId", type => Int) recipeId: number, @Ctx() { entityManager }: ContextType) { + @Query(_returns => Recipe, { nullable: true }) + recipe(@Arg("recipeId", _type => Int) recipeId: number, @Ctx() { entityManager }: Context) { return entityManager.findOne(Recipe, recipeId); } - @Query(returns => [Recipe]) - recipes(@Ctx() { entityManager }: ContextType): Promise { + @Query(_returns => [Recipe]) + recipes(@Ctx() { entityManager }: Context): Promise { return entityManager.find(Recipe, {}); } - @Mutation(returns => Recipe) + @Mutation(_returns => Recipe) async addRecipe( @Arg("recipe") recipeInput: RecipeInput, - @Ctx() { user, entityManager }: ContextType, + @Ctx() { user, entityManager }: Context, ): Promise { const recipe = entityManager.create(Recipe, { title: recipeInput.title, @@ -33,12 +29,12 @@ export class RecipeResolver { return recipe; } - @Mutation(returns => Recipe) + @Mutation(_returns => Recipe) async rate( - @Arg("rate") rateInput: RateInput, - @Ctx() { user, entityManager }: ContextType, + @Arg("rate") rateInput: RatingInput, + @Ctx() { user, entityManager }: Context, ): Promise { - // find the recipe + // Find the recipe const recipe = await entityManager.findOne(Recipe, rateInput.recipeId, { populate: ["ratings"], }); @@ -46,26 +42,27 @@ export class RecipeResolver { throw new Error("Invalid recipe ID"); } - // set the new recipe rate - const newRate = entityManager.create(Rate, { + // Set the new recipe rating + const newRating = entityManager.create(Rating, { recipe, value: rateInput.value, user: entityManager.getReference(User, user.id), }); - recipe.ratings.add(newRate); + recipe.ratings.add(newRating); - // update the recipe + // Update the recipe await entityManager.persistAndFlush(recipe); + return recipe; } @FieldResolver() - ratings(@Root() recipe: Recipe, @Ctx() { entityManager }: ContextType) { - return entityManager.find(Rate, { recipe: { id: recipe.id } }); + ratings(@Root() recipe: Recipe, @Ctx() { entityManager }: Context) { + return entityManager.find(Rating, { recipe: { id: recipe.id } }); } @FieldResolver() - async author(@Root() recipe: Recipe, @Ctx() { entityManager }: ContextType): Promise { + async author(@Root() recipe: Recipe, @Ctx() { entityManager }: Context): Promise { return entityManager.findOneOrFail(User, recipe.author.id); } } diff --git a/examples/mikro-orm/resolvers/types/index.ts b/examples/mikro-orm/resolvers/types/index.ts new file mode 100644 index 000000000..0538b5ca4 --- /dev/null +++ b/examples/mikro-orm/resolvers/types/index.ts @@ -0,0 +1,2 @@ +export * from "./rating.input"; +export * from "./recipe.input"; diff --git a/examples/mikro-orm/resolvers/types/rating.input.ts b/examples/mikro-orm/resolvers/types/rating.input.ts new file mode 100644 index 000000000..cdff2e505 --- /dev/null +++ b/examples/mikro-orm/resolvers/types/rating.input.ts @@ -0,0 +1,10 @@ +import { Field, InputType, Int } from "type-graphql"; + +@InputType() +export class RatingInput { + @Field(_type => Int) + recipeId!: number; + + @Field(_type => Int) + value!: number; +} diff --git a/examples/mikro-orm/resolvers/inputs/recipe-input.ts b/examples/mikro-orm/resolvers/types/recipe.input.ts similarity index 53% rename from examples/mikro-orm/resolvers/inputs/recipe-input.ts rename to examples/mikro-orm/resolvers/types/recipe.input.ts index b2c157c91..5a75d4cb8 100644 --- a/examples/mikro-orm/resolvers/inputs/recipe-input.ts +++ b/examples/mikro-orm/resolvers/types/recipe.input.ts @@ -1,11 +1,10 @@ -import { InputType, Field } from "../../../../src"; - -import { Recipe } from "../../entities/recipe"; +import { Field, InputType } from "type-graphql"; +import { type Recipe } from "../../entities"; @InputType() export class RecipeInput implements Partial { @Field() - title: string; + title!: string; @Field({ nullable: true }) description?: string; diff --git a/examples/mikro-orm/schema.gql b/examples/mikro-orm/schema.graphql similarity index 56% rename from examples/mikro-orm/schema.gql rename to examples/mikro-orm/schema.graphql index 2e6a6fc72..860d97148 100644 --- a/examples/mikro-orm/schema.gql +++ b/examples/mikro-orm/schema.graphql @@ -4,13 +4,13 @@ # ----------------------------------------------- """ -The javascript `Date` as string. Type represents date and time as the ISO Date string. +A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar.This scalar is serialized to a string in ISO 8601 format and parsed from a string in ISO 8601 format. """ -scalar DateTime +scalar DateTimeISO type Mutation { addRecipe(recipe: RecipeInput!): Recipe! - rate(rate: RateInput!): Recipe! + rate(rate: RatingInput!): Recipe! } type Query { @@ -18,13 +18,13 @@ type Query { recipes: [Recipe!]! } -type Rate { - date: DateTime! +type Rating { + date: DateTimeISO! user: User! value: Int! } -input RateInput { +input RatingInput { recipeId: Int! value: Int! } @@ -33,7 +33,7 @@ type Recipe { author: User! description: String id: ID! - ratings: [Rate!]! + ratings: [Rating!]! title: String! } diff --git a/examples/mikro-orm/types.ts b/examples/mikro-orm/types.ts deleted file mode 100644 index e865fcaa7..000000000 --- a/examples/mikro-orm/types.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { EntityManager } from "@mikro-orm/core"; - -import { User } from "./entities/user"; - -export interface ContextType { - entityManager: EntityManager; - user: User; -} diff --git a/examples/mixin-classes/examples.gql b/examples/mixin-classes/examples.graphql similarity index 100% rename from examples/mixin-classes/examples.gql rename to examples/mixin-classes/examples.graphql diff --git a/examples/mixin-classes/index.ts b/examples/mixin-classes/index.ts index ec0fa50d5..8b50e93d6 100644 --- a/examples/mixin-classes/index.ts +++ b/examples/mixin-classes/index.ts @@ -1,24 +1,27 @@ import "reflect-metadata"; -import { ApolloServer } from "apollo-server"; -import * as path from "path"; -import { buildSchema } from "../../src"; - -import UserResolver from "./resolver"; +import path from "node:path"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { buildSchema } from "type-graphql"; +import { UserResolver } from "./resolver"; async function bootstrap() { - // build TypeGraphQL executable schema + // Build TypeGraphQL executable schema const schema = await buildSchema({ + // Array of resolvers resolvers: [UserResolver], - emitSchemaFile: path.resolve(__dirname, "schema.gql"), + // Create 'schema.graphql' file with schema definition in current directory + emitSchemaFile: path.resolve(__dirname, "schema.graphql"), skipCheck: true, + validate: true, }); // Create GraphQL server const server = new ApolloServer({ schema }); - // Start the server - const { url } = await server.listen(4000); - console.log(`Server is running, GraphQL Playground available at ${url}`); + // Start server + const { url } = await startStandaloneServer(server, { listen: { port: 4000 } }); + console.log(`GraphQL server ready at ${url}`); } bootstrap().catch(console.error); diff --git a/examples/mixin-classes/inputs/amend-user.ts b/examples/mixin-classes/inputs/amend-user.ts deleted file mode 100644 index b36bec26c..000000000 --- a/examples/mixin-classes/inputs/amend-user.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { InputType } from "../../../src"; - -import withId from "../mixins/with-id"; -import UserDetails from "../types/user-details"; - -// `AmendUser` is like the full `User` class without the password -@InputType() -export default class AmendUserInput extends withId(UserDetails) {} diff --git a/examples/mixin-classes/inputs/amend.user.input.ts b/examples/mixin-classes/inputs/amend.user.input.ts new file mode 100644 index 000000000..8405a84d6 --- /dev/null +++ b/examples/mixin-classes/inputs/amend.user.input.ts @@ -0,0 +1,7 @@ +import { InputType } from "type-graphql"; +import { withId } from "../mixins"; +import { UserDetails } from "../types"; + +// 'AmendUser' is like the full 'User' class without the password +@InputType() +export class AmendUserInput extends withId(UserDetails) {} diff --git a/examples/mixin-classes/inputs/create-user.ts b/examples/mixin-classes/inputs/create-user.ts deleted file mode 100644 index 4db90cac3..000000000 --- a/examples/mixin-classes/inputs/create-user.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { InputType } from "../../../src"; - -import withPassword from "../mixins/with-password"; -import UserDetails from "../types/user-details"; - -// `CreateUser` is like the full `User` class without the id -@InputType() -export default class CreateUserInput extends withPassword(UserDetails) {} diff --git a/examples/mixin-classes/inputs/create.user.input.ts b/examples/mixin-classes/inputs/create.user.input.ts new file mode 100644 index 000000000..d0824c6d7 --- /dev/null +++ b/examples/mixin-classes/inputs/create.user.input.ts @@ -0,0 +1,7 @@ +import { InputType } from "type-graphql"; +import { withPassword } from "../mixins"; +import { UserDetails } from "../types"; + +// 'CreateUser' is like the full 'User' class without the id +@InputType() +export class CreateUserInput extends withPassword(UserDetails) {} diff --git a/examples/mixin-classes/inputs/index.ts b/examples/mixin-classes/inputs/index.ts new file mode 100644 index 000000000..c2d75157a --- /dev/null +++ b/examples/mixin-classes/inputs/index.ts @@ -0,0 +1,2 @@ +export * from "./amend.user.input"; +export * from "./create.user.input"; diff --git a/examples/mixin-classes/mixins/index.ts b/examples/mixin-classes/mixins/index.ts new file mode 100644 index 000000000..dcdbc5141 --- /dev/null +++ b/examples/mixin-classes/mixins/index.ts @@ -0,0 +1,2 @@ +export * from "./with.id"; +export * from "./with.password"; diff --git a/examples/mixin-classes/mixins/with-id.ts b/examples/mixin-classes/mixins/with-id.ts deleted file mode 100644 index f261ad58d..000000000 --- a/examples/mixin-classes/mixins/with-id.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { InputType, ClassType, Field, Int, ObjectType } from "../../../src"; - -// adds id property to the base, extended class -export default function withId(BaseClass: TClassType) { - @ObjectType({ isAbstract: true }) - @InputType({ isAbstract: true }) - class IDTrait extends BaseClass { - @Field(type => Int) - id!: number; - } - return IDTrait; -} diff --git a/examples/mixin-classes/mixins/with-password.ts b/examples/mixin-classes/mixins/with-password.ts deleted file mode 100644 index 1e7108d4f..000000000 --- a/examples/mixin-classes/mixins/with-password.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { MinLength } from "class-validator"; -import { InputType, ClassType, Field, ObjectType } from "../../../src"; - -// adds password property with validation to the base, extended class -export default function withPassword(BaseClass: TClassType) { - @ObjectType({ isAbstract: true }) - @InputType({ isAbstract: true }) - class PasswordTrait extends BaseClass { - @MinLength(8) - @Field() - password!: string; - } - return PasswordTrait; -} diff --git a/examples/mixin-classes/mixins/with.id.ts b/examples/mixin-classes/mixins/with.id.ts new file mode 100644 index 000000000..d837d2dac --- /dev/null +++ b/examples/mixin-classes/mixins/with.id.ts @@ -0,0 +1,13 @@ +import { type ClassType, Field, InputType, Int, ObjectType } from "type-graphql"; + +// Adds 'id' property to the base, extended class +export function withId(BaseClass: TClassType) { + @ObjectType() + @InputType() + class IDTrait extends BaseClass { + @Field(_type => Int) + id!: number; + } + + return IDTrait; +} diff --git a/examples/mixin-classes/mixins/with.password.ts b/examples/mixin-classes/mixins/with.password.ts new file mode 100644 index 000000000..d599d6806 --- /dev/null +++ b/examples/mixin-classes/mixins/with.password.ts @@ -0,0 +1,15 @@ +import { MinLength } from "class-validator"; +import { type ClassType, Field, InputType, ObjectType } from "type-graphql"; + +// Adds 'password' property with validation to the base, extended class +export function withPassword(BaseClass: TClassType) { + @ObjectType() + @InputType() + class PasswordTrait extends BaseClass { + @MinLength(8) + @Field() + password!: string; + } + + return PasswordTrait; +} diff --git a/examples/mixin-classes/resolver.ts b/examples/mixin-classes/resolver.ts index 089396fc9..47c28f043 100644 --- a/examples/mixin-classes/resolver.ts +++ b/examples/mixin-classes/resolver.ts @@ -1,30 +1,30 @@ -import { Resolver, Mutation, Arg, Query } from "../../src"; - -import CreateUserInput from "./inputs/create-user"; -import AmendUserInput from "./inputs/amend-user"; -import User from "./types/user"; +import { Arg, Mutation, Query, Resolver } from "type-graphql"; +import { AmendUserInput, CreateUserInput } from "./inputs"; +import { User } from "./types"; @Resolver() -export default class UserResolver { +export class UserResolver { private autoIncrementId = 0; + private readonly usersData: User[] = []; - @Query(returns => [User]) + @Query(_returns => [User]) async users(): Promise { return this.usersData; } - @Mutation(returns => User) + @Mutation(_returns => User) async createUser(@Arg("input") userData: CreateUserInput): Promise { - // in createUser we generate the ID and store the password - const user: User = { ...userData, id: ++this.autoIncrementId }; + // Generate the ID and store the password + this.autoIncrementId += 1; + const user: User = { ...userData, id: this.autoIncrementId }; this.usersData.push(user); return user; } - @Mutation(returns => User) + @Mutation(_returns => User) async amendUser(@Arg("input") { id, ...userData }: AmendUserInput): Promise { - // in amendUser we use receive the ID but can't change the password + // Receive the ID but can't change the password const user = this.usersData.find(it => it.id === id); if (!user) { throw new Error(`Invalid ID: ${id}`); diff --git a/examples/mixin-classes/schema.gql b/examples/mixin-classes/schema.graphql similarity index 58% rename from examples/mixin-classes/schema.gql rename to examples/mixin-classes/schema.graphql index 114e2ce05..b26eff9f7 100644 --- a/examples/mixin-classes/schema.gql +++ b/examples/mixin-classes/schema.graphql @@ -4,7 +4,7 @@ # ----------------------------------------------- input AmendUserInput { - dateOfBirth: DateTime! + dateOfBirth: DateTimeISO! email: String! forename: String! id: Int! @@ -12,7 +12,7 @@ input AmendUserInput { } input CreateUserInput { - dateOfBirth: DateTime! + dateOfBirth: DateTimeISO! email: String! forename: String! password: String! @@ -20,9 +20,9 @@ input CreateUserInput { } """ -The javascript `Date` as string. Type represents date and time as the ISO Date string. +A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar.This scalar is serialized to a string in ISO 8601 format and parsed from a string in ISO 8601 format. """ -scalar DateTime +scalar DateTimeISO type Mutation { amendUser(input: AmendUserInput!): User! @@ -34,7 +34,7 @@ type Query { } type User { - dateOfBirth: DateTime! + dateOfBirth: DateTimeISO! email: String! forename: String! id: Int! diff --git a/examples/mixin-classes/types/index.ts b/examples/mixin-classes/types/index.ts new file mode 100644 index 000000000..8fd62bb5f --- /dev/null +++ b/examples/mixin-classes/types/index.ts @@ -0,0 +1,2 @@ +export * from "./user"; +export * from "./user.details"; diff --git a/examples/mixin-classes/types/user-details.ts b/examples/mixin-classes/types/user-details.ts deleted file mode 100644 index acc275362..000000000 --- a/examples/mixin-classes/types/user-details.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { IsEmail } from "class-validator"; -import { InputType, Field, ObjectType } from "../../../src"; - -// `UserDetails` stores base common user properties -@ObjectType({ isAbstract: true }) -@InputType("UserDetailsInput", { isAbstract: true }) -export default class UserDetails { - @Field() - forename!: string; - - @Field({ nullable: true }) - surname?: string; - - @Field(type => Date) - dateOfBirth!: Date; - - @IsEmail() - @Field() - email!: string; -} diff --git a/examples/mixin-classes/types/user.details.ts b/examples/mixin-classes/types/user.details.ts new file mode 100644 index 000000000..aaa8019ea --- /dev/null +++ b/examples/mixin-classes/types/user.details.ts @@ -0,0 +1,20 @@ +import { IsEmail } from "class-validator"; +import { Field, InputType, ObjectType } from "type-graphql"; + +// 'UserDetails' stores base common user properties +@ObjectType() +@InputType("UserDetailsInput") +export class UserDetails { + @Field() + forename!: string; + + @Field({ nullable: true }) + surname?: string; + + @Field(_type => Date) + dateOfBirth!: Date; + + @IsEmail() + @Field() + email!: string; +} diff --git a/examples/mixin-classes/types/user.ts b/examples/mixin-classes/types/user.ts index 83ccc82cf..b87e52478 100644 --- a/examples/mixin-classes/types/user.ts +++ b/examples/mixin-classes/types/user.ts @@ -1,11 +1,10 @@ -import { ObjectType } from "../../../src"; +import { ObjectType } from "type-graphql"; +import { UserDetails } from "./user.details"; +import { withId } from "../mixins/with.id"; -import withId from "../mixins/with-id"; -import UserDetails from "./user-details"; - -// `User` is a full object with id and hidden password +// 'User' is a full object with 'id' and hidden 'password' @ObjectType() -export default class User extends withId(UserDetails) { - // no TypeGraphQL decorator - hidden in schema +export class User extends withId(UserDetails) { + // No TypeGraphQL decorator, hidden in schema password!: string; } diff --git a/examples/query-complexity/examples.gql b/examples/query-complexity/examples.graphql similarity index 100% rename from examples/query-complexity/examples.gql rename to examples/query-complexity/examples.graphql diff --git a/examples/query-complexity/index.ts b/examples/query-complexity/index.ts index 8c62d430a..3b86110b2 100644 --- a/examples/query-complexity/index.ts +++ b/examples/query-complexity/index.ts @@ -1,60 +1,67 @@ import "reflect-metadata"; -import { ApolloServer } from "apollo-server"; -import { getComplexity, simpleEstimator, fieldExtensionsEstimator } from "graphql-query-complexity"; -import { buildSchema } from "../../src"; +import path from "node:path"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { fieldExtensionsEstimator, getComplexity, simpleEstimator } from "graphql-query-complexity"; +import { buildSchema } from "type-graphql"; +import { RecipeResolver } from "./recipe.resolver"; -import { RecipeResolver } from "./recipe-resolver"; +// Maximum allowed complexity +const MAX_COMPLEXITY = 20; async function bootstrap() { // Build TypeGraphQL executable schema const schema = await buildSchema({ + // Array of resolvers resolvers: [RecipeResolver], + // Create 'schema.graphql' file with schema definition in current directory + emitSchemaFile: path.resolve(__dirname, "schema.graphql"), }); // Create GraphQL server const server = new ApolloServer({ schema, - // Create a plugin that will allow for query complexity calculation for every request + // Create a plugin to allow query complexity calculation for every request plugins: [ { - requestDidStart: () => ({ - didResolveOperation({ request, document }) { + requestDidStart: async () => ({ + async didResolveOperation({ request, document }) { /** - * This provides GraphQL query analysis to be able to react on complex queries to your GraphQL server. - * This can be used to protect your GraphQL servers against resource exhaustion and DoS attacks. - * More documentation can be found at https://github.com/ivome/graphql-query-complexity. + * Provides GraphQL query analysis to be able to react on complex queries to the GraphQL server + * It can be used to protect the GraphQL server against resource exhaustion and DoS attacks + * More documentation can be found at https://github.com/ivome/graphql-query-complexity */ const complexity = getComplexity({ - // Our built schema + // GraphQL schema schema, // To calculate query complexity properly, - // we have to check only the requested operation + // check only the requested operation // not the whole document that may contains multiple operations operationName: request.operationName, - // The GraphQL query document + // GraphQL query document query: document, - // The variables for our GraphQL query + // GraphQL query variables variables: request.variables, // Add any number of estimators. The estimators are invoked in order, the first - // numeric value that is being returned by an estimator is used as the field complexity. - // If no estimator returns a value, an exception is raised. + // numeric value that is being returned by an estimator is used as the field complexity + // If no estimator returns a value, an exception is raised estimators: [ - // Using fieldExtensionsEstimator is mandatory to make it work with type-graphql. + // Using fieldExtensionsEstimator is mandatory to make it work with type-graphql fieldExtensionsEstimator(), // Add more estimators here... // This will assign each field a complexity of 1 - // if no other estimator returned a value. + // if no other estimator returned a value simpleEstimator({ defaultComplexity: 1 }), ], }); - // Here we can react to the calculated complexity, - // like compare it with max and throw error when the threshold is reached. - if (complexity > 20) { + + // React to the calculated complexity, + // like compare it with max and throw error when the threshold is reached + if (complexity > MAX_COMPLEXITY) { throw new Error( - `Sorry, too complicated query! ${complexity} is over 20 that is the max allowed complexity.`, + `Sorry, too complicated query! ${complexity} exceeded the maximum allowed complexity of ${MAX_COMPLEXITY}`, ); } - // And here we can e.g. subtract the complexity point from hourly API calls limit. console.log("Used query complexity points:", complexity); }, }), @@ -62,9 +69,9 @@ async function bootstrap() { ], }); - // Start the server - const { url } = await server.listen(4000); - console.log(`Server is running, GraphQL Playground available at ${url}`); + // Start server + const { url } = await startStandaloneServer(server, { listen: { port: 4000 } }); + console.log(`GraphQL server ready at ${url}`); } -bootstrap(); +bootstrap().catch(console.error); diff --git a/examples/query-complexity/recipe-resolver.ts b/examples/query-complexity/recipe-resolver.ts deleted file mode 100644 index ff37c3b17..000000000 --- a/examples/query-complexity/recipe-resolver.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Resolver, Query, FieldResolver, Root, ResolverInterface, Arg } from "../../src"; - -import { Recipe } from "./recipe-type"; -import { createRecipeSamples } from "./recipe-samples"; - -@Resolver(of => Recipe) -export class RecipeResolver implements ResolverInterface { - private readonly items: Recipe[] = createRecipeSamples(); - - @Query(returns => [Recipe], { - /* - You can also pass a calculation function in the complexity option - to determine a custom complexity. This function will provide the - complexity of the child nodes as well as the field input arguments. - That way you can make a more realistic estimation of individual field - complexity values, e.g. by multiplying childComplexity by the number of items in array - */ - complexity: ({ childComplexity, args }) => args.count * childComplexity, - }) - async recipes(@Arg("count") count: number): Promise { - return await this.items.slice(0, count); - } - - /* Complexity in field resolver overrides complexity of equivalent field type */ - @FieldResolver({ complexity: 5 }) - ratingsCount(@Root() recipe: Recipe): number { - return recipe.ratings.length; - } -} diff --git a/examples/query-complexity/recipe-samples.ts b/examples/query-complexity/recipe.data.ts similarity index 91% rename from examples/query-complexity/recipe-samples.ts rename to examples/query-complexity/recipe.data.ts index 4caf3f50b..291f96614 100644 --- a/examples/query-complexity/recipe-samples.ts +++ b/examples/query-complexity/recipe.data.ts @@ -1,4 +1,8 @@ -import { Recipe } from "./recipe-type"; +import { Recipe } from "./recipe.type"; + +function createRecipe(recipeData: Partial): Recipe { + return Object.assign(new Recipe(), recipeData); +} export function createRecipeSamples() { return [ @@ -16,7 +20,3 @@ export function createRecipeSamples() { }), ]; } - -function createRecipe(recipeData: Partial): Recipe { - return Object.assign(new Recipe(), recipeData); -} diff --git a/examples/query-complexity/recipe.resolver.ts b/examples/query-complexity/recipe.resolver.ts new file mode 100644 index 000000000..0e71b6bd4 --- /dev/null +++ b/examples/query-complexity/recipe.resolver.ts @@ -0,0 +1,28 @@ +import { Arg, FieldResolver, Query, Resolver, type ResolverInterface, Root } from "type-graphql"; +import { createRecipeSamples } from "./recipe.data"; +import { Recipe } from "./recipe.type"; + +@Resolver(_of => Recipe) +export class RecipeResolver implements ResolverInterface { + private readonly items: Recipe[] = createRecipeSamples(); + + @Query(_returns => [Recipe], { + /* + Pass also a calculation function in the complexity option + to determine a custom complexity. This function provide the + complexity of the child nodes as well as the field input arguments. + That way a more realistic estimation of individual field + complexity values is made, e.g. by multiplying childComplexity by the number of items in array + */ + complexity: ({ childComplexity, args }) => args.count * childComplexity, + }) + async recipes(@Arg("count") count: number): Promise { + return this.items.slice(0, count); + } + + /* Complexity in field resolver overrides complexity of equivalent field type */ + @FieldResolver({ complexity: 5 }) + ratingsCount(@Root() recipe: Recipe): number { + return recipe.ratings.length; + } +} diff --git a/examples/query-complexity/recipe-type.ts b/examples/query-complexity/recipe.type.ts similarity index 58% rename from examples/query-complexity/recipe-type.ts rename to examples/query-complexity/recipe.type.ts index f921fe1d9..899394532 100644 --- a/examples/query-complexity/recipe-type.ts +++ b/examples/query-complexity/recipe.type.ts @@ -1,16 +1,16 @@ -import { Field, ObjectType, Int, Float } from "../../src"; +import { Field, Float, Int, ObjectType } from "type-graphql"; @ObjectType() export class Recipe { - /* By default, every field gets a complexity of 1. */ + /* By default, every field gets a complexity of 1 */ @Field() - title: string; + title!: string; /* Which can be customized by passing the complexity parameter */ - @Field(type => Int, { complexity: 2 }) - ratingsCount: number; + @Field(_type => Int, { complexity: 2 }) + ratingsCount!: number; - @Field(type => Float, { + @Field(_type => Float, { nullable: true, complexity: 10, }) @@ -23,6 +23,6 @@ export class Recipe { return ratingsSum / ratingsCount; } - // internal property, not exposed in schema - ratings: number[]; + // Internal property, not exposed in schema + ratings!: number[]; } diff --git a/examples/graphql-modules/user/user-schema.gql b/examples/query-complexity/schema.graphql similarity index 68% rename from examples/graphql-modules/user/user-schema.gql rename to examples/query-complexity/schema.graphql index e0ff89cca..87d9a6797 100644 --- a/examples/graphql-modules/user/user-schema.gql +++ b/examples/query-complexity/schema.graphql @@ -4,16 +4,11 @@ # ----------------------------------------------- type Query { - users: [User!]! + recipes(count: Float!): [Recipe!]! } type Recipe { - author: User! -} - -type User { - age: Int! - email: String! - id: Int! - name: String! + averageRating: Float + ratingsCount: Int! + title: String! } diff --git a/examples/redis-subscriptions/.env.example b/examples/redis-subscriptions/.env.example new file mode 100644 index 000000000..9f29f58b5 --- /dev/null +++ b/examples/redis-subscriptions/.env.example @@ -0,0 +1 @@ +REDIS_URL="redis://username:password@localhost:6379/0" diff --git a/examples/redis-subscriptions/comment.input.ts b/examples/redis-subscriptions/comment.input.ts index 381bbf7ad..b5721aead 100644 --- a/examples/redis-subscriptions/comment.input.ts +++ b/examples/redis-subscriptions/comment.input.ts @@ -1,15 +1,14 @@ -import { Field, ID, InputType } from "../../src"; - -import { Comment } from "./comment.type"; +import { Field, ID, InputType } from "type-graphql"; +import { type Comment } from "./comment.type"; @InputType() export class CommentInput implements Partial { - @Field(type => ID) - recipeId: string; + @Field(_type => ID) + recipeId!: string; @Field({ nullable: true }) nickname?: string; @Field() - content: string; + content!: string; } diff --git a/examples/redis-subscriptions/comment.type.ts b/examples/redis-subscriptions/comment.type.ts index 5296c1989..69538b7a7 100644 --- a/examples/redis-subscriptions/comment.type.ts +++ b/examples/redis-subscriptions/comment.type.ts @@ -1,4 +1,4 @@ -import { Field, ObjectType } from "../../src"; +import { Field, ObjectType } from "type-graphql"; @ObjectType() export class Comment { @@ -6,8 +6,18 @@ export class Comment { nickname?: string; @Field() - content: string; + content!: string; @Field() - date: Date; + date!: Date; +} + +export interface NewCommentPayload { + recipeId: string; + + dateString: string; // Limitation of Redis payload serialization + + content: string; + + nickname?: string; } diff --git a/examples/redis-subscriptions/examples.gql b/examples/redis-subscriptions/examples.graphql similarity index 56% rename from examples/redis-subscriptions/examples.gql rename to examples/redis-subscriptions/examples.graphql index 15dab7377..7ce211d6c 100644 --- a/examples/redis-subscriptions/examples.gql +++ b/examples/redis-subscriptions/examples.graphql @@ -1,5 +1,5 @@ query FirstRecipe { - recipe(id:"1") { + recipe(id: "1") { title description comments { @@ -11,19 +11,11 @@ query FirstRecipe { } mutation AddCommentToRecipe1 { - addNewComment(comment: { - recipeId: "1", - nickname: "MichalLytek", - content: "Nice one!" - }) + addNewComment(comment: { recipeId: "1", nickname: "MichalLytek", content: "Nice one!" }) } mutation AddCommentToRecipe2 { - addNewComment(comment: { - recipeId: "2", - nickname: "MichalLytek", - content: "Nice two!" - }) + addNewComment(comment: { recipeId: "2", nickname: "MichalLytek", content: "Nice two!" }) } subscription NewCommentsForRecipe2 { diff --git a/examples/redis-subscriptions/index.ts b/examples/redis-subscriptions/index.ts index cd4e39571..8fc6ccfa3 100644 --- a/examples/redis-subscriptions/index.ts +++ b/examples/redis-subscriptions/index.ts @@ -1,41 +1,37 @@ import "reflect-metadata"; -import { ApolloServer } from "apollo-server"; -import Redis from "ioredis"; -import { RedisPubSub } from "graphql-redis-subscriptions"; -import { buildSchema } from "../../src"; - +import "dotenv/config"; +import http from "node:http"; +import path from "node:path"; +import { createYoga } from "graphql-yoga"; +import { buildSchema } from "type-graphql"; +import { pubSub } from "./pubsub"; import { RecipeResolver } from "./recipe.resolver"; -const REDIS_HOST = "192.168.99.100"; // replace with own IP -const REDIS_PORT = 6379; - async function bootstrap() { - // configure Redis connection options - const options: Redis.RedisOptions = { - host: REDIS_HOST, - port: REDIS_PORT, - retryStrategy: times => Math.max(times * 100, 3000), - }; - - // create Redis-based pub-sub - const pubSub = new RedisPubSub({ - publisher: new Redis(options), - subscriber: new Redis(options), - }); - - // Build the TypeGraphQL schema + // Build TypeGraphQL executable schema const schema = await buildSchema({ + // Array of resolvers resolvers: [RecipeResolver], + // Create 'schema.graphql' file with schema definition in current directory + emitSchemaFile: path.resolve(__dirname, "schema.graphql"), + // Publish/Subscribe + pubSub, validate: false, - pubSub, // provide redis-based instance of PubSub }); // Create GraphQL server - const server = new ApolloServer({ schema }); + const yoga = createYoga({ + schema, + graphqlEndpoint: "/graphql", + }); - // Start the server - const { url } = await server.listen(4000); - console.log(`Server is running, GraphQL Playground available at ${url}`); + // Create server + const httpServer = http.createServer(yoga); + + // Start server + httpServer.listen(4000, () => { + console.log(`GraphQL server ready at http://localhost:4000/graphql`); + }); } -bootstrap(); +bootstrap().catch(console.error); diff --git a/examples/redis-subscriptions/newComment.interface.ts b/examples/redis-subscriptions/newComment.interface.ts deleted file mode 100644 index 09f469ac0..000000000 --- a/examples/redis-subscriptions/newComment.interface.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface NewCommentPayload { - recipeId: string; - dateString: string; // limitation of Redis payload serialization - content: string; - nickname?: string; -} diff --git a/examples/redis-subscriptions/pubsub.ts b/examples/redis-subscriptions/pubsub.ts new file mode 100644 index 000000000..1e72eb1f0 --- /dev/null +++ b/examples/redis-subscriptions/pubsub.ts @@ -0,0 +1,26 @@ +import { createRedisEventTarget } from "@graphql-yoga/redis-event-target"; +import { createPubSub } from "@graphql-yoga/subscription"; +import { Redis } from "ioredis"; +import { type NewCommentPayload } from "./comment.type"; + +const redisUrl = process.env.REDIS_URL; +if (!redisUrl) { + throw new Error("REDIS_URL env variable is not defined"); +} + +export const enum Topic { + NEW_COMMENT = "NEW_COMMENT", +} + +export const pubSub = createPubSub<{ + [Topic.NEW_COMMENT]: [NewCommentPayload]; +}>({ + eventTarget: createRedisEventTarget({ + publishClient: new Redis(redisUrl, { + retryStrategy: times => Math.max(times * 100, 3000), + }), + subscribeClient: new Redis(redisUrl, { + retryStrategy: times => Math.max(times * 100, 3000), + }), + }), +}); diff --git a/examples/redis-subscriptions/recipe.samples.ts b/examples/redis-subscriptions/recipe.data.ts similarity index 100% rename from examples/redis-subscriptions/recipe.samples.ts rename to examples/redis-subscriptions/recipe.data.ts index 2b4e210cf..eca3f3802 100644 --- a/examples/redis-subscriptions/recipe.samples.ts +++ b/examples/redis-subscriptions/recipe.data.ts @@ -1,5 +1,13 @@ -import { Recipe } from "./recipe.type"; import { Comment } from "./comment.type"; +import { Recipe } from "./recipe.type"; + +function createRecipe(recipeData: Partial): Recipe { + return Object.assign(new Recipe(), recipeData); +} + +function createComment(commentData: Partial): Comment { + return Object.assign(new Comment(), commentData); +} export const sampleRecipes = [ createRecipe({ @@ -37,11 +45,3 @@ export const sampleRecipes = [ comments: [], }), ]; - -function createRecipe(recipeData: Partial): Recipe { - return Object.assign(new Recipe(), recipeData); -} - -function createComment(commentData: Partial): Comment { - return Object.assign(new Comment(), commentData); -} diff --git a/examples/redis-subscriptions/recipe.resolver.args.ts b/examples/redis-subscriptions/recipe.resolver.args.ts index 08628d7dd..2ddb1ff90 100644 --- a/examples/redis-subscriptions/recipe.resolver.args.ts +++ b/examples/redis-subscriptions/recipe.resolver.args.ts @@ -1,7 +1,7 @@ -import { ID, Field, ArgsType } from "../../src"; +import { ArgsType, Field, ID } from "type-graphql"; @ArgsType() export class NewCommentsArgs { - @Field(type => ID) - recipeId: string; + @Field(_type => ID) + recipeId!: string; } diff --git a/examples/redis-subscriptions/recipe.resolver.ts b/examples/redis-subscriptions/recipe.resolver.ts index d1b3d2678..0e6c07463 100644 --- a/examples/redis-subscriptions/recipe.resolver.ts +++ b/examples/redis-subscriptions/recipe.resolver.ts @@ -1,72 +1,64 @@ import { - Resolver, - Query, - Mutation, Arg, - PubSub, - Publisher, - Subscription, - Root, - ID, - ResolverFilterData, Args, -} from "../../src"; - -import { Recipe } from "./recipe.type"; + ID, + Mutation, + Query, + Resolver, + Root, + Subscription, + type SubscriptionHandlerData, +} from "type-graphql"; import { CommentInput } from "./comment.input"; -import { Comment } from "./comment.type"; -import { NewCommentPayload } from "./newComment.interface"; -import { Topic } from "./topics"; -import { sampleRecipes } from "./recipe.samples"; +import { Comment, NewCommentPayload } from "./comment.type"; +import { Topic, pubSub } from "./pubsub"; +import { sampleRecipes } from "./recipe.data"; import { NewCommentsArgs } from "./recipe.resolver.args"; +import { Recipe } from "./recipe.type"; @Resolver() export class RecipeResolver { private readonly recipes: Recipe[] = sampleRecipes.slice(); - @Query(returns => Recipe, { nullable: true }) - async recipe(@Arg("id", type => ID) id: string) { + @Query(_returns => Recipe, { nullable: true }) + async recipe(@Arg("id", _type => ID) id: string) { return this.recipes.find(recipe => recipe.id === id); } - @Mutation(returns => Boolean) - async addNewComment( - @Arg("comment") input: CommentInput, - @PubSub(Topic.NewComment) notifyAboutNewComment: Publisher, - ): Promise { + @Mutation(_returns => Boolean) + async addNewComment(@Arg("comment") input: CommentInput): Promise { const recipe = this.recipes.find(r => r.id === input.recipeId); if (!recipe) { return false; } + const comment: Comment = { content: input.content, nickname: input.nickname, date: new Date(), }; recipe.comments.push(comment); - await notifyAboutNewComment({ + + pubSub.publish(Topic.NEW_COMMENT, { content: comment.content, nickname: comment.nickname, dateString: comment.date.toISOString(), recipeId: input.recipeId, }); + return true; } - @Subscription(returns => Comment, { - topics: Topic.NewComment, - filter: ({ payload, args }: ResolverFilterData) => { - return payload.recipeId === args.recipeId; - }, + @Subscription(_returns => Comment, { + topics: Topic.NEW_COMMENT, + filter: ({ payload, args }: SubscriptionHandlerData) => + payload.recipeId === args.recipeId, }) - newComments( - @Root() newComment: NewCommentPayload, - @Args() { recipeId }: NewCommentsArgs, - ): Comment { + newComments(@Root() newComment: NewCommentPayload, @Args() _args: NewCommentsArgs): Comment { return { content: newComment.content, - date: new Date(newComment.dateString), // limitation of Redis payload serialization + date: new Date(newComment.dateString), // Limitation of Redis payload serialization nickname: newComment.nickname, - }; + } satisfies Comment; } } diff --git a/examples/redis-subscriptions/recipe.type.ts b/examples/redis-subscriptions/recipe.type.ts index 546967c6b..4c7c34650 100644 --- a/examples/redis-subscriptions/recipe.type.ts +++ b/examples/redis-subscriptions/recipe.type.ts @@ -1,18 +1,17 @@ -import { ObjectType, Field, ID } from "../../src"; - +import { Field, ID, ObjectType } from "type-graphql"; import { Comment } from "./comment.type"; @ObjectType() export class Recipe { - @Field(type => ID) - id: string; + @Field(_type => ID) + id!: string; @Field() - title: string; + title!: string; @Field({ nullable: true }) description?: string; - @Field(type => [Comment]) - comments: Comment[]; + @Field(_type => [Comment]) + comments!: Comment[]; } diff --git a/examples/redis-subscriptions/schema.graphql b/examples/redis-subscriptions/schema.graphql new file mode 100644 index 000000000..d582f79dd --- /dev/null +++ b/examples/redis-subscriptions/schema.graphql @@ -0,0 +1,40 @@ +# ----------------------------------------------- +# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!! +# !!! DO NOT MODIFY THIS FILE BY YOURSELF !!! +# ----------------------------------------------- + +type Comment { + content: String! + date: DateTimeISO! + nickname: String +} + +input CommentInput { + content: String! + nickname: String + recipeId: ID! +} + +""" +A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar.This scalar is serialized to a string in ISO 8601 format and parsed from a string in ISO 8601 format. +""" +scalar DateTimeISO + +type Mutation { + addNewComment(comment: CommentInput!): Boolean! +} + +type Query { + recipe(id: ID!): Recipe +} + +type Recipe { + comments: [Comment!]! + description: String + id: ID! + title: String! +} + +type Subscription { + newComments(recipeId: ID!): Comment! +} diff --git a/examples/redis-subscriptions/topics.ts b/examples/redis-subscriptions/topics.ts deleted file mode 100644 index e9eb6344c..000000000 --- a/examples/redis-subscriptions/topics.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum Topic { - NewComment = "NEW_COMMENT", - NewRecipe = "NEW_RECIPE", -} diff --git a/examples/resolvers-inheritance/queries.gql b/examples/resolvers-inheritance/examples.graphql similarity index 87% rename from examples/resolvers-inheritance/queries.gql rename to examples/resolvers-inheritance/examples.graphql index 644c394dd..0f0cc3e82 100644 --- a/examples/resolvers-inheritance/queries.gql +++ b/examples/resolvers-inheritance/examples.graphql @@ -16,6 +16,6 @@ query OneRecipe { } } -mutation PromotePeronsOne { +mutation PromotePersonOne { promote(personId: 1) } diff --git a/examples/resolvers-inheritance/index.ts b/examples/resolvers-inheritance/index.ts index cfe820389..dbc356695 100644 --- a/examples/resolvers-inheritance/index.ts +++ b/examples/resolvers-inheritance/index.ts @@ -1,24 +1,29 @@ import "reflect-metadata"; -import { ApolloServer } from "apollo-server"; +import path from "node:path"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { buildSchema } from "type-graphql"; import { Container } from "typedi"; -import { buildSchema } from "../../src"; - -import { RecipeResolver } from "./recipe/recipe.resolver"; -import { PersonResolver } from "./person/person.resolver"; +import { PersonResolver } from "./person"; +import { RecipeResolver } from "./recipe"; async function bootstrap() { - // build TypeGraphQL executable schema + // Build TypeGraphQL executable schema const schema = await buildSchema({ + // Array of resolvers resolvers: [RecipeResolver, PersonResolver], + // Create 'schema.graphql' file with schema definition in current directory + emitSchemaFile: path.resolve(__dirname, "schema.graphql"), + // Registry 3rd party IOC container container: Container, }); // Create GraphQL server const server = new ApolloServer({ schema }); - // Start the server - const { url } = await server.listen(4000); - console.log(`Server is running, GraphQL Playground available at ${url}`); + // Start server + const { url } = await startStandaloneServer(server, { listen: { port: 4000 } }); + console.log(`GraphQL server ready at ${url}`); } -bootstrap(); +bootstrap().catch(console.error); diff --git a/examples/resolvers-inheritance/person/index.ts b/examples/resolvers-inheritance/person/index.ts new file mode 100644 index 000000000..9bdfaf321 --- /dev/null +++ b/examples/resolvers-inheritance/person/index.ts @@ -0,0 +1,3 @@ +export * from "./person.resolver"; +export * from "./person.role"; +export * from "./person.type"; diff --git a/examples/resolvers-inheritance/person/person.resolver.ts b/examples/resolvers-inheritance/person/person.resolver.ts index c05eeef4b..15aaaff7d 100644 --- a/examples/resolvers-inheritance/person/person.resolver.ts +++ b/examples/resolvers-inheritance/person/person.resolver.ts @@ -1,8 +1,8 @@ -import { Resolver, Arg, Int, Mutation } from "../../../src"; - -import { ResourceResolver } from "../resource/resource.resolver"; -import { Person } from "./person.type"; +import { Arg, Int, Mutation, Resolver } from "type-graphql"; +import { Service } from "typedi"; import { PersonRole } from "./person.role"; +import { Person } from "./person.type"; +import { ResourceResolver } from "../resource"; const persons: Person[] = [ { @@ -20,12 +20,13 @@ const persons: Person[] = [ ]; @Resolver() +@Service() export class PersonResolver extends ResourceResolver(Person, persons) { - // here you can add resource-specific operations + // Here you can add resource-specific operations @Mutation() - promote(@Arg("personId", type => Int) personId: number): boolean { - // you have full access to base resolver class fields and methods + promote(@Arg("personId", _type => Int) personId: number): boolean { + // Full access to base resolver class fields and methods const person = this.resourceService.getOne(personId); if (!person) { diff --git a/examples/resolvers-inheritance/person/person.role.ts b/examples/resolvers-inheritance/person/person.role.ts index a3ee95ac3..014873137 100644 --- a/examples/resolvers-inheritance/person/person.role.ts +++ b/examples/resolvers-inheritance/person/person.role.ts @@ -1,4 +1,4 @@ -import { registerEnumType } from "../../../src"; +import { registerEnumType } from "type-graphql"; export enum PersonRole { Normal, diff --git a/examples/resolvers-inheritance/person/person.type.ts b/examples/resolvers-inheritance/person/person.type.ts index 0f5955ea1..417b62132 100644 --- a/examples/resolvers-inheritance/person/person.type.ts +++ b/examples/resolvers-inheritance/person/person.type.ts @@ -1,19 +1,18 @@ -import { ObjectType, Field, Int } from "../../../src"; - -import { Resource } from "../resource/resource"; +import { Field, Int, ObjectType } from "type-graphql"; import { PersonRole } from "./person.role"; +import { type Resource } from "../resource"; @ObjectType() export class Person implements Resource { @Field() - id: number; + id!: number; @Field() - name: string; + name!: string; - @Field(type => Int) - age: number; + @Field(_type => Int) + age!: number; - @Field(type => PersonRole) - role: PersonRole; + @Field(_type => PersonRole) + role!: PersonRole; } diff --git a/examples/resolvers-inheritance/recipe/index.ts b/examples/resolvers-inheritance/recipe/index.ts new file mode 100644 index 000000000..717325557 --- /dev/null +++ b/examples/resolvers-inheritance/recipe/index.ts @@ -0,0 +1,2 @@ +export * from "./recipe.resolver"; +export * from "./recipe.type"; diff --git a/examples/resolvers-inheritance/recipe/recipe.resolver.ts b/examples/resolvers-inheritance/recipe/recipe.resolver.ts index d5337e0cb..28540f09c 100644 --- a/examples/resolvers-inheritance/recipe/recipe.resolver.ts +++ b/examples/resolvers-inheritance/recipe/recipe.resolver.ts @@ -1,7 +1,7 @@ -import { Resolver, FieldResolver, Root } from "../../../src"; - -import { ResourceResolver } from "../resource/resource.resolver"; +import { FieldResolver, Resolver, Root } from "type-graphql"; +import { Service } from "typedi"; import { Recipe } from "./recipe.type"; +import { ResourceResolver } from "../resource"; const recipes: Recipe[] = [ { @@ -11,9 +11,10 @@ const recipes: Recipe[] = [ }, ]; -@Resolver(of => Recipe) +@Resolver(_of => Recipe) +@Service() export class RecipeResolver extends ResourceResolver(Recipe, recipes) { - // here you can add resource-specific operations + // Here you can add resource-specific operations @FieldResolver() averageRating(@Root() recipe: Recipe): number { diff --git a/examples/resolvers-inheritance/recipe/recipe.type.ts b/examples/resolvers-inheritance/recipe/recipe.type.ts index 62edb1a23..fb304a297 100644 --- a/examples/resolvers-inheritance/recipe/recipe.type.ts +++ b/examples/resolvers-inheritance/recipe/recipe.type.ts @@ -1,15 +1,14 @@ -import { ObjectType, Field, Int } from "../../../src"; - -import { Resource } from "../resource/resource"; +import { Field, Int, ObjectType } from "type-graphql"; +import { type Resource } from "../resource"; @ObjectType() export class Recipe implements Resource { @Field() - id: number; + id!: number; @Field() - title: string; + title!: string; - @Field(type => [Int]) - ratings: number[]; + @Field(_type => [Int]) + ratings!: number[]; } diff --git a/examples/resolvers-inheritance/resource/index.ts b/examples/resolvers-inheritance/resource/index.ts new file mode 100644 index 000000000..7ed5a1cf5 --- /dev/null +++ b/examples/resolvers-inheritance/resource/index.ts @@ -0,0 +1,5 @@ +export * from "./resource.args"; +export * from "./resource"; +export * from "./resource.resolver"; +export * from "./resource.service"; +export * from "./resource.service.factory"; diff --git a/examples/resolvers-inheritance/resource/resource.args.ts b/examples/resolvers-inheritance/resource/resource.args.ts new file mode 100644 index 000000000..22257c170 --- /dev/null +++ b/examples/resolvers-inheritance/resource/resource.args.ts @@ -0,0 +1,10 @@ +import { ArgsType, Field, Int } from "type-graphql"; + +@ArgsType() +export class GetAllArgs { + @Field(_type => Int) + skip = 0; + + @Field(_type => Int) + take = 10; +} diff --git a/examples/resolvers-inheritance/resource/resource.resolver.ts b/examples/resolvers-inheritance/resource/resource.resolver.ts index 7e388b88c..9d184e483 100644 --- a/examples/resolvers-inheritance/resource/resource.resolver.ts +++ b/examples/resolvers-inheritance/resource/resource.resolver.ts @@ -1,28 +1,9 @@ +import { Arg, Args, type ClassType, FieldResolver, Int, Query, Resolver, Root } from "type-graphql"; import { Service } from "typedi"; -import { - Query, - Arg, - Int, - Resolver, - ArgsType, - Field, - Args, - FieldResolver, - Root, - ClassType, -} from "../../../src"; - import { Resource } from "./resource"; -import { ResourceService, ResourceServiceFactory } from "./resource.service"; - -@ArgsType() -export class GetAllArgs { - @Field(type => Int) - skip: number = 0; - - @Field(type => Int) - take: number = 10; -} +import { GetAllArgs } from "./resource.args"; +import { type ResourceService } from "./resource.service"; +import { ResourceServiceFactory } from "./resource.service.factory"; export function ResourceResolver( ResourceCls: ClassType, @@ -30,8 +11,7 @@ export function ResourceResolver( ) { const resourceName = ResourceCls.name.toLocaleLowerCase(); - // `isAbstract` decorator option is mandatory to prevent multiple registering in schema - @Resolver(of => ResourceCls, { isAbstract: true }) + @Resolver(_of => ResourceCls) @Service() abstract class ResourceResolverClass { protected resourceService: ResourceService; @@ -40,18 +20,18 @@ export function ResourceResolver( this.resourceService = factory.create(resources); } - @Query(returns => ResourceCls, { name: `${resourceName}` }) - protected async getOne(@Arg("id", type => Int) id: number) { + @Query(_returns => ResourceCls, { name: `${resourceName}` }) + protected async getOne(@Arg("id", _type => Int) id: number) { return this.resourceService.getOne(id); } - @Query(returns => [ResourceCls], { name: `${resourceName}s` }) + @Query(_returns => [ResourceCls], { name: `${resourceName}s` }) protected async getAll(@Args() { skip, take }: GetAllArgs) { const all = this.resourceService.getAll(skip, take); return all; } - // dynamically created field with resolver for all child resource classes + // Dynamically created field with resolver for all child resource classes @FieldResolver({ name: "uuid" }) protected getUuid(@Root() resource: Resource): string { return `${resourceName}_${resource.id}`; diff --git a/examples/resolvers-inheritance/resource/resource.service.factory.ts b/examples/resolvers-inheritance/resource/resource.service.factory.ts new file mode 100644 index 000000000..5308181c5 --- /dev/null +++ b/examples/resolvers-inheritance/resource/resource.service.factory.ts @@ -0,0 +1,11 @@ +import { Service } from "typedi"; +import { type Resource } from "./resource"; +import { ResourceService } from "./resource.service"; + +// Use factory to separate instance of service for each generic +@Service() +export class ResourceServiceFactory { + create(resources?: TResource[]) { + return new ResourceService(resources); + } +} diff --git a/examples/resolvers-inheritance/resource/resource.service.ts b/examples/resolvers-inheritance/resource/resource.service.ts index cfe1286de..4edbb9c7a 100644 --- a/examples/resolvers-inheritance/resource/resource.service.ts +++ b/examples/resolvers-inheritance/resource/resource.service.ts @@ -1,14 +1,4 @@ -import { Service } from "typedi"; - -import { Resource } from "./resource"; - -// we need to use factory as we need separate instance of service for each generic -@Service() -export class ResourceServiceFactory { - create(resources?: TResource[]) { - return new ResourceService(resources); - } -} +import { type Resource } from "./resource"; export class ResourceService { constructor(protected resources: TResource[] = []) {} diff --git a/examples/resolvers-inheritance/schema.graphql b/examples/resolvers-inheritance/schema.graphql new file mode 100644 index 000000000..b41b815ff --- /dev/null +++ b/examples/resolvers-inheritance/schema.graphql @@ -0,0 +1,37 @@ +# ----------------------------------------------- +# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!! +# !!! DO NOT MODIFY THIS FILE BY YOURSELF !!! +# ----------------------------------------------- + +type Mutation { + promote(personId: Int!): Boolean! +} + +type Person { + age: Int! + id: Float! + name: String! + role: PersonRole! + uuid: String! +} + +enum PersonRole { + Admin + Normal + Pro +} + +type Query { + person(id: Int!): Person! + persons(skip: Int! = 0, take: Int! = 10): [Person!]! + recipe(id: Int!): Recipe! + recipes(skip: Int! = 0, take: Int! = 10): [Recipe!]! +} + +type Recipe { + averageRating: Float! + id: Float! + ratings: [Int!]! + title: String! + uuid: String! +} diff --git a/examples/simple-subscriptions/examples.gql b/examples/simple-subscriptions/examples.gql deleted file mode 100644 index 5f5a62f5a..000000000 --- a/examples/simple-subscriptions/examples.gql +++ /dev/null @@ -1,32 +0,0 @@ -subscription AllNotifications { - normalSubscription { - id - message - date - } -} - -subscription EvenNotifications { - subscriptionWithFilter { - id - message - date - } -} - -mutation PublishMessage { - pubSubMutation(message: "Hello") -} - -# dynamic topics - -subscription DynamicTopic { - subscriptionWithFilterToDynamicTopic(topic: "FOO_MESSAGES") { - id - message - } -} - -mutation PublishMessageToDynamicTopic { - pubSubMutationToDynamicTopic(topic: "FOO_MESSAGES", message: "Hi Foo!") -} diff --git a/examples/simple-subscriptions/examples.graphql b/examples/simple-subscriptions/examples.graphql new file mode 100644 index 000000000..38b87391a --- /dev/null +++ b/examples/simple-subscriptions/examples.graphql @@ -0,0 +1,45 @@ +subscription AllNotifications { + normalSubscription { + id + message + date + } +} + +subscription EvenNotifications { + subscriptionWithFilter { + id + message + date + } +} + +mutation PublishMessage { + pubSubMutation(message: "Hello") +} + +# Dynamic topics + +subscription DynamicTopic { + subscribeToTopicFromArg(topic: "FOO_MESSAGES") { + id + message + } +} + +mutation PublishMessageToDynamicTopic { + publishToDynamicTopic(topic: "FOO_MESSAGES", message: "Hi Foo!") +} + +# Dynamic topic id + +subscription DynamicTopicId { + subscribeToTopicIdFromArg(topicId: 2137) { + id + message + } +} + +mutation PublishMessageToDynamicTopicId { + publishWithDynamicTopicId(topicId: 2137, message: "Hi Foo!") +} diff --git a/examples/simple-subscriptions/index.ts b/examples/simple-subscriptions/index.ts index 300bd47db..368932ca6 100644 --- a/examples/simple-subscriptions/index.ts +++ b/examples/simple-subscriptions/index.ts @@ -1,27 +1,35 @@ import "reflect-metadata"; -import { ApolloServer } from "apollo-server"; -import { buildSchema } from "../../src"; - -import { SampleResolver } from "./resolver"; +import http from "node:http"; +import path from "node:path"; +import { createYoga } from "graphql-yoga"; +import { buildSchema } from "type-graphql"; +import { NotificationResolver } from "./notification.resolver"; +import { pubSub } from "./pubsub"; async function bootstrap() { - // Build the TypeGraphQL schema + // Build TypeGraphQL executable schema const schema = await buildSchema({ - resolvers: [SampleResolver], + // Array of resolvers + resolvers: [NotificationResolver], + // Create 'schema.graphql' file with schema definition in current directory + emitSchemaFile: path.resolve(__dirname, "schema.graphql"), + // Publish/Subscribe + pubSub, }); // Create GraphQL server - const server = new ApolloServer({ + const yoga = createYoga({ schema, - playground: true, - // you can pass the endpoint path for subscriptions - // otherwise it will be the same as main graphql endpoint - // subscriptions: "/subscriptions", + graphqlEndpoint: "/graphql", }); - // Start the server - const { url } = await server.listen(4000); - console.log(`Server is running, GraphQL Playground available at ${url}`); + // Create server + const httpServer = http.createServer(yoga); + + // Start server + httpServer.listen(4000, () => { + console.log(`GraphQL server ready at http://localhost:4000/graphql`); + }); } -bootstrap(); +bootstrap().catch(console.error); diff --git a/examples/simple-subscriptions/notification.resolver.ts b/examples/simple-subscriptions/notification.resolver.ts new file mode 100644 index 000000000..fd6f3d86e --- /dev/null +++ b/examples/simple-subscriptions/notification.resolver.ts @@ -0,0 +1,103 @@ +import { + Arg, + Int, + Mutation, + Query, + Resolver, + Root, + type SubscribeResolverData, + Subscription, + type SubscriptionHandlerData, +} from "type-graphql"; +import { Notification, NotificationPayload } from "./notification.type"; +import { Topic, pubSub } from "./pubsub"; + +@Resolver() +export class NotificationResolver { + private id: number = 0; + + @Query(_returns => Date) + currentDate() { + return new Date(); + } + + @Mutation(_returns => Boolean) + async pubSubMutation(@Arg("message", { nullable: true }) message?: string): Promise { + this.id += 1; + const payload: NotificationPayload = { id: this.id, message }; + pubSub.publish(Topic.NOTIFICATIONS, payload); + return true; + } + + @Subscription({ topics: Topic.NOTIFICATIONS }) + normalSubscription(@Root() { id, message }: NotificationPayload): Notification { + return { id, message, date: new Date() }; + } + + @Subscription(_returns => Notification, { + topics: Topic.NOTIFICATIONS, + filter: ({ payload }: SubscriptionHandlerData) => payload.id % 2 === 0, + }) + subscriptionWithFilter(@Root() { id, message }: NotificationPayload) { + const newNotification: Notification = { id, message, date: new Date() }; + return newNotification; + } + + // Multiple topics + + @Subscription(_returns => Notification, { + topics: [Topic.NOTIFICATIONS, "NOTIFICATIONS_2"], + filter: ({ payload }: SubscriptionHandlerData) => payload.id % 2 === 0, + }) + subscriptionWithMultipleTopics(@Root() { id, message }: NotificationPayload) { + const newNotification: Notification = { id, message, date: new Date() }; + return newNotification; + } + + // Dynamic topic + + @Mutation(() => Boolean) + async publishToDynamicTopic( + @Arg("topic") topic: string, + @Arg("message", { nullable: true }) message?: string, + ): Promise { + this.id += 1; + const payload: NotificationPayload = { id: this.id, message }; + pubSub.publish(topic, payload); + return true; + } + + @Subscription({ + topics: ({ args }) => args.topic, + }) + subscribeToTopicFromArg( + @Arg("topic") _topic: string, + @Root() { id, message }: NotificationPayload, + ): Notification { + return { id, message, date: new Date() }; + } + + // Dynamic topic id + + @Mutation(() => Boolean) + async publishWithDynamicTopicId( + @Arg("topicId", () => Int) topicId: number, + @Arg("message", { nullable: true }) message?: string, + ): Promise { + this.id += 1; + const payload: NotificationPayload = { id: this.id, message }; + pubSub.publish(Topic.DYNAMIC_ID_TOPIC, topicId, payload); + return true; + } + + @Subscription({ + topics: Topic.DYNAMIC_ID_TOPIC, + topicId: ({ args }: SubscribeResolverData) => args.topicId, + }) + subscribeToTopicIdFromArg( + @Arg("topicId", () => Int) _topicId: number, + @Root() { id, message }: NotificationPayload, + ): Notification { + return { id, message, date: new Date() }; + } +} diff --git a/examples/simple-subscriptions/notification.type.ts b/examples/simple-subscriptions/notification.type.ts index d0ed23b7b..394cb726f 100644 --- a/examples/simple-subscriptions/notification.type.ts +++ b/examples/simple-subscriptions/notification.type.ts @@ -1,18 +1,19 @@ -import { ObjectType, Field, ID } from "../../src"; +import { Field, ID, ObjectType } from "type-graphql"; @ObjectType() export class Notification { - @Field(type => ID) - id: number; + @Field(_type => ID) + id!: number; @Field({ nullable: true }) message?: string; - @Field(type => Date) - date: Date; + @Field(_type => Date) + date!: Date; } export interface NotificationPayload { id: number; + message?: string; } diff --git a/examples/simple-subscriptions/pubsub.ts b/examples/simple-subscriptions/pubsub.ts new file mode 100644 index 000000000..726227db9 --- /dev/null +++ b/examples/simple-subscriptions/pubsub.ts @@ -0,0 +1,14 @@ +import { createPubSub } from "@graphql-yoga/subscription"; +import { type NotificationPayload } from "./notification.type"; + +export const enum Topic { + NOTIFICATIONS = "NOTIFICATIONS", + DYNAMIC_ID_TOPIC = "DYNAMIC_ID_TOPIC", +} + +export const pubSub = createPubSub< + { + [Topic.NOTIFICATIONS]: [NotificationPayload]; + [Topic.DYNAMIC_ID_TOPIC]: [number, NotificationPayload]; + } & Record // Fallback for dynamic topics +>(); diff --git a/examples/simple-subscriptions/resolver.ts b/examples/simple-subscriptions/resolver.ts deleted file mode 100644 index f450d85b4..000000000 --- a/examples/simple-subscriptions/resolver.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { PubSubEngine } from "graphql-subscriptions"; -import { - Resolver, - Query, - Mutation, - Arg, - PubSub, - Publisher, - Subscription, - Root, - ResolverFilterData, -} from "../../src"; - -import { Notification, NotificationPayload } from "./notification.type"; - -@Resolver() -export class SampleResolver { - private autoIncrement = 0; - - @Query(returns => Date) - currentDate() { - return new Date(); - } - - @Mutation(returns => Boolean) - async pubSubMutation( - @PubSub() pubSub: PubSubEngine, - @Arg("message", { nullable: true }) message?: string, - ): Promise { - const payload: NotificationPayload = { id: ++this.autoIncrement, message }; - await pubSub.publish("NOTIFICATIONS", payload); - return true; - } - - @Mutation(returns => Boolean) - async publisherMutation( - @PubSub("NOTIFICATIONS") publish: Publisher, - @Arg("message", { nullable: true }) message?: string, - ): Promise { - await publish({ id: ++this.autoIncrement, message }); - return true; - } - - @Subscription({ topics: "NOTIFICATIONS" }) - normalSubscription(@Root() { id, message }: NotificationPayload): Notification { - return { id, message, date: new Date() }; - } - - @Subscription(returns => Notification, { - topics: "NOTIFICATIONS", - filter: ({ payload }: ResolverFilterData) => payload.id % 2 === 0, - }) - subscriptionWithFilter(@Root() { id, message }: NotificationPayload) { - const newNotification: Notification = { id, message, date: new Date() }; - return newNotification; - } - - // dynamic topic - - @Mutation(returns => Boolean) - async pubSubMutationToDynamicTopic( - @PubSub() pubSub: PubSubEngine, - @Arg("topic") topic: string, - @Arg("message", { nullable: true }) message?: string, - ): Promise { - const payload: NotificationPayload = { id: ++this.autoIncrement, message }; - await pubSub.publish(topic, payload); - return true; - } - - @Subscription({ - topics: ({ args }) => args.topic, - }) - subscriptionWithFilterToDynamicTopic( - @Arg("topic") topic: string, - @Root() { id, message }: NotificationPayload, - ): Notification { - return { id, message, date: new Date() }; - } -} diff --git a/examples/simple-subscriptions/schema.graphql b/examples/simple-subscriptions/schema.graphql new file mode 100644 index 000000000..003dc69f5 --- /dev/null +++ b/examples/simple-subscriptions/schema.graphql @@ -0,0 +1,33 @@ +# ----------------------------------------------- +# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!! +# !!! DO NOT MODIFY THIS FILE BY YOURSELF !!! +# ----------------------------------------------- + +""" +A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar.This scalar is serialized to a string in ISO 8601 format and parsed from a string in ISO 8601 format. +""" +scalar DateTimeISO + +type Mutation { + pubSubMutation(message: String): Boolean! + publishToDynamicTopic(message: String, topic: String!): Boolean! + publishWithDynamicTopicId(message: String, topicId: Int!): Boolean! +} + +type Notification { + date: DateTimeISO! + id: ID! + message: String +} + +type Query { + currentDate: DateTimeISO! +} + +type Subscription { + normalSubscription: Notification! + subscribeToTopicFromArg(topic: String!): Notification! + subscribeToTopicIdFromArg(topicId: Int!): Notification! + subscriptionWithFilter: Notification! + subscriptionWithMultipleTopics: Notification! +} diff --git a/examples/simple-usage/examples.graphql b/examples/simple-usage/examples.graphql new file mode 100644 index 000000000..35edc9e98 --- /dev/null +++ b/examples/simple-usage/examples.graphql @@ -0,0 +1,25 @@ +query GetRecipe1 { + recipe(title: "Recipe 1") { + title + description + ratings + creationDate + ratingsCount(minRate: 2) + averageRating + } +} + +query GetRecipes { + recipes { + title + description + creationDate + averageRating + } +} + +mutation AddRecipe { + addRecipe(recipe: { title: "New recipe", description: "Simple description" }) { + creationDate + } +} diff --git a/examples/simple-usage/index.ts b/examples/simple-usage/index.ts index aa5ddaafb..76a69d3f5 100644 --- a/examples/simple-usage/index.ts +++ b/examples/simple-usage/index.ts @@ -1,28 +1,25 @@ import "reflect-metadata"; -import { ApolloServer } from "apollo-server"; -import * as path from "path"; -import { buildSchema } from "../../src"; - -import { RecipeResolver } from "./recipe-resolver"; +import path from "node:path"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { buildSchema } from "type-graphql"; +import { RecipeResolver } from "./recipe.resolver"; async function bootstrap() { - // build TypeGraphQL executable schema + // Build TypeGraphQL executable schema const schema = await buildSchema({ + // Array of resolvers resolvers: [RecipeResolver], - // automatically create `schema.gql` file with schema definition in current folder - emitSchemaFile: path.resolve(__dirname, "schema.gql"), + // Create 'schema.graphql' file with schema definition in current directory + emitSchemaFile: path.resolve(__dirname, "schema.graphql"), }); // Create GraphQL server - const server = new ApolloServer({ - schema, - // enable GraphQL Playground - playground: true, - }); + const server = new ApolloServer({ schema }); - // Start the server - const { url } = await server.listen(4000); - console.log(`Server is running, GraphQL Playground available at ${url}`); + // Start server + const { url } = await startStandaloneServer(server, { listen: { port: 4000 } }); + console.log(`GraphQL server ready at ${url}`); } -bootstrap(); +bootstrap().catch(console.error); diff --git a/examples/simple-usage/recipe.data.ts b/examples/simple-usage/recipe.data.ts new file mode 100644 index 000000000..e82854f9b --- /dev/null +++ b/examples/simple-usage/recipe.data.ts @@ -0,0 +1,28 @@ +import { Recipe } from "./recipe.type"; + +function createRecipe(recipeData: Partial) { + return Object.assign(new Recipe(), recipeData); +} + +export function createRecipeSamples() { + return [ + createRecipe({ + description: "Desc 1", + title: "Recipe 1", + ratings: [0, 3, 1], + creationDate: new Date("2018-04-11"), + }), + createRecipe({ + description: "Desc 2", + title: "Recipe 2", + ratings: [4, 2, 3, 1], + creationDate: new Date("2018-04-15"), + }), + createRecipe({ + description: "Desc 3", + title: "Recipe 3", + ratings: [5, 4], + creationDate: new Date(), + }), + ]; +} diff --git a/examples/simple-usage/recipe-input.ts b/examples/simple-usage/recipe.input.ts similarity index 54% rename from examples/simple-usage/recipe-input.ts rename to examples/simple-usage/recipe.input.ts index d3496b743..764dd2162 100644 --- a/examples/simple-usage/recipe-input.ts +++ b/examples/simple-usage/recipe.input.ts @@ -1,10 +1,10 @@ -import { Recipe } from "./recipe-type"; -import { InputType, Field } from "../../src"; +import { Field, InputType } from "type-graphql"; +import { type Recipe } from "./recipe.type"; @InputType() export class RecipeInput implements Partial { @Field() - title: string; + title!: string; @Field({ nullable: true }) description?: string; diff --git a/examples/simple-usage/recipe-resolver.ts b/examples/simple-usage/recipe.resolver.ts similarity index 59% rename from examples/simple-usage/recipe-resolver.ts rename to examples/simple-usage/recipe.resolver.ts index 4b2e24dbc..b03c7aaa9 100644 --- a/examples/simple-usage/recipe-resolver.ts +++ b/examples/simple-usage/recipe.resolver.ts @@ -1,33 +1,32 @@ import { - Resolver, - Query, - FieldResolver, Arg, - Root, - Mutation, + FieldResolver, Int, - ResolverInterface, -} from "../../src"; - -import { Recipe } from "./recipe-type"; -import { RecipeInput } from "./recipe-input"; -import { createRecipeSamples } from "./recipe-samples"; + Mutation, + Query, + Resolver, + type ResolverInterface, + Root, +} from "type-graphql"; +import { createRecipeSamples } from "./recipe.data"; +import { RecipeInput } from "./recipe.input"; +import { Recipe } from "./recipe.type"; -@Resolver(of => Recipe) +@Resolver(_of => Recipe) export class RecipeResolver implements ResolverInterface { private readonly items: Recipe[] = createRecipeSamples(); - @Query(returns => Recipe, { nullable: true }) + @Query(_returns => Recipe, { nullable: true }) async recipe(@Arg("title") title: string): Promise { - return await this.items.find(recipe => recipe.title === title); + return this.items.find(recipe => recipe.title === title); } - @Query(returns => [Recipe], { description: "Get all the recipes from around the world " }) + @Query(_returns => [Recipe], { description: "Get all the recipes from around the world " }) async recipes(): Promise { - return await this.items; + return this.items; } - @Mutation(returns => Recipe) + @Mutation(_returns => Recipe) async addRecipe(@Arg("recipe") recipeInput: RecipeInput): Promise { const recipe = Object.assign(new Recipe(), { description: recipeInput.description, @@ -36,13 +35,14 @@ export class RecipeResolver implements ResolverInterface { creationDate: new Date(), }); await this.items.push(recipe); + return recipe; } @FieldResolver() ratingsCount( @Root() recipe: Recipe, - @Arg("minRate", type => Int, { defaultValue: 0.0 }) minRate: number, + @Arg("minRate", _type => Int, { defaultValue: 0 }) minRate: number, ): number { return recipe.ratings.filter(rating => rating >= minRate).length; } diff --git a/examples/simple-usage/recipe-type.ts b/examples/simple-usage/recipe.type.ts similarity index 61% rename from examples/simple-usage/recipe-type.ts rename to examples/simple-usage/recipe.type.ts index 2cdc9a224..a9b265d65 100644 --- a/examples/simple-usage/recipe-type.ts +++ b/examples/simple-usage/recipe.type.ts @@ -1,11 +1,11 @@ -import { Field, ObjectType, Int, Float } from "../../src"; +import { Field, Float, Int, ObjectType } from "type-graphql"; @ObjectType({ description: "Object representing cooking recipe" }) export class Recipe { @Field() - title: string; + title!: string; - @Field(type => String, { nullable: true, deprecationReason: "Use `description` field instead" }) + @Field(_type => String, { nullable: true, deprecationReason: "Use 'description' field instead" }) get specification(): string | undefined { return this.description; } @@ -13,22 +13,23 @@ export class Recipe { @Field({ nullable: true, description: "The recipe description with preparation info" }) description?: string; - @Field(type => [Int]) - ratings: number[]; + @Field(_type => [Int]) + ratings!: number[]; @Field() - creationDate: Date; + creationDate!: Date; - @Field(type => Int) - ratingsCount: number; + @Field(_type => Int) + ratingsCount!: number; - @Field(type => Float, { nullable: true }) + @Field(_type => Float, { nullable: true }) get averageRating(): number | null { const ratingsCount = this.ratings.length; if (ratingsCount === 0) { return null; } const ratingsSum = this.ratings.reduce((a, b) => a + b, 0); + return ratingsSum / ratingsCount; } } diff --git a/examples/simple-usage/schema.gql b/examples/simple-usage/schema.gql deleted file mode 100644 index f2d492a24..000000000 --- a/examples/simple-usage/schema.gql +++ /dev/null @@ -1,38 +0,0 @@ -# ----------------------------------------------- -# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!! -# !!! DO NOT MODIFY THIS FILE BY YOURSELF !!! -# ----------------------------------------------- - -""" -The javascript `Date` as string. Type represents date and time as the ISO Date string. -""" -scalar DateTime - -type Mutation { - addRecipe(recipe: RecipeInput!): Recipe! -} - -type Query { - recipe(title: String!): Recipe - - """Get all the recipes from around the world """ - recipes: [Recipe!]! -} - -"""Object representing cooking recipe""" -type Recipe { - averageRating: Float - creationDate: DateTime! - - """The recipe description with preparation info""" - description: String - ratings: [Int!]! - ratingsCount(minRate: Int = 0): Int! - specification: String @deprecated(reason: "Use `description` field instead") - title: String! -} - -input RecipeInput { - description: String - title: String! -} diff --git a/examples/simple-usage/schema.graphql b/examples/simple-usage/schema.graphql new file mode 100644 index 000000000..b379f89c8 --- /dev/null +++ b/examples/simple-usage/schema.graphql @@ -0,0 +1,44 @@ +# ----------------------------------------------- +# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!! +# !!! DO NOT MODIFY THIS FILE BY YOURSELF !!! +# ----------------------------------------------- + +""" +A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar.This scalar is serialized to a string in ISO 8601 format and parsed from a string in ISO 8601 format. +""" +scalar DateTimeISO + +type Mutation { + addRecipe(recipe: RecipeInput!): Recipe! +} + +type Query { + recipe(title: String!): Recipe + + """ + Get all the recipes from around the world + """ + recipes: [Recipe!]! +} + +""" +Object representing cooking recipe +""" +type Recipe { + averageRating: Float + creationDate: DateTimeISO! + + """ + The recipe description with preparation info + """ + description: String + ratings: [Int!]! + ratingsCount(minRate: Int! = 0): Int! + specification: String @deprecated(reason: "Use 'description' field instead") + title: String! +} + +input RecipeInput { + description: String + title: String! +} diff --git a/examples/tsconfig.json b/examples/tsconfig.json index 2405dfb48..beb1deb19 100644 --- a/examples/tsconfig.json +++ b/examples/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "../tsconfig.json", + "extends": "../tsconfig.cjs.json", + "include": ["../src", "./"], "compilerOptions": { - "declaration": false, - }, - "include": [".", "../src"] + "emitDecoratorMetadata": true + } } diff --git a/examples/using-container/examples.gql b/examples/tsyringe/examples.graphql similarity index 70% rename from examples/using-container/examples.gql rename to examples/tsyringe/examples.graphql index b69c4d482..637acc8de 100644 --- a/examples/using-container/examples.gql +++ b/examples/tsyringe/examples.graphql @@ -17,14 +17,7 @@ query GetRecipes { } mutation AddRecipe { - addRecipe(recipe: { - title: "New recipe", - ingredients: [ - "One", - "Two", - "Three", - ], - }) { + addRecipe(recipe: { title: "New recipe", ingredients: ["One", "Two", "Three"] }) { id numberInCollection } diff --git a/examples/tsyringe/index.ts b/examples/tsyringe/index.ts new file mode 100644 index 000000000..5295ca48f --- /dev/null +++ b/examples/tsyringe/index.ts @@ -0,0 +1,32 @@ +import "reflect-metadata"; +import path from "node:path"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { container } from "tsyringe"; +import { buildSchema } from "type-graphql"; +import { sampleRecipes } from "./recipe.data"; +import { RecipeResolver } from "./recipe.resolver"; + +// Add sample recipes in container +container.register("SAMPLE_RECIPES", { useValue: sampleRecipes.slice() }); + +async function bootstrap() { + // Build TypeGraphQL executable schema + const schema = await buildSchema({ + // Array of resolvers + resolvers: [RecipeResolver], + // Registry 3rd party IOC container + container: { get: cls => container.resolve(cls) }, + // Create 'schema.graphql' file with schema definition in current directory + emitSchemaFile: path.resolve(__dirname, "schema.graphql"), + }); + + // Create GraphQL server + const server = new ApolloServer({ schema }); + + // Start server + const { url } = await startStandaloneServer(server, { listen: { port: 4000 } }); + console.log(`GraphQL server ready at ${url}`); +} + +bootstrap().catch(console.error); diff --git a/examples/using-container/sample-recipes.ts b/examples/tsyringe/recipe.data.ts similarity index 92% rename from examples/using-container/sample-recipes.ts rename to examples/tsyringe/recipe.data.ts index 45ceac97e..288d850e5 100644 --- a/examples/using-container/sample-recipes.ts +++ b/examples/tsyringe/recipe.data.ts @@ -1,4 +1,8 @@ -import { Recipe } from "./recipe-type"; +import { Recipe } from "./recipe.type"; + +function createRecipe(recipeData: Partial): Recipe { + return Object.assign(new Recipe(), recipeData); +} export const sampleRecipes = [ createRecipe({ @@ -19,7 +23,3 @@ export const sampleRecipes = [ ingredients: ["seven", "eight", "nine"], }), ]; - -function createRecipe(recipeData: Partial): Recipe { - return Object.assign(new Recipe(), recipeData); -} diff --git a/examples/tsyringe/recipe.input.ts b/examples/tsyringe/recipe.input.ts new file mode 100644 index 000000000..97ec17bce --- /dev/null +++ b/examples/tsyringe/recipe.input.ts @@ -0,0 +1,14 @@ +import { Field, InputType } from "type-graphql"; +import { type Recipe } from "./recipe.type"; + +@InputType() +export class RecipeInput implements Partial { + @Field() + title!: string; + + @Field({ nullable: true }) + description?: string; + + @Field(_type => [String]) + ingredients!: string[]; +} diff --git a/examples/tsyringe/recipe.resolver.ts b/examples/tsyringe/recipe.resolver.ts new file mode 100644 index 000000000..9fc087f5e --- /dev/null +++ b/examples/tsyringe/recipe.resolver.ts @@ -0,0 +1,36 @@ +import { inject, injectable } from "tsyringe"; +import { Arg, FieldResolver, Mutation, Query, Resolver, Root } from "type-graphql"; +import { RecipeInput } from "./recipe.input"; +import { RecipeService } from "./recipe.service"; +import { Recipe } from "./recipe.type"; + +@injectable() +@Resolver(_of => Recipe) +export class RecipeResolver { + constructor( + // Inject service + @inject(RecipeService) + private readonly recipeService: RecipeService, + ) {} + + @Query(_returns => Recipe, { nullable: true }) + async recipe(@Arg("recipeId") recipeId: string) { + return this.recipeService.getOne(recipeId); + } + + @Query(_returns => [Recipe]) + async recipes(): Promise { + return this.recipeService.getAll(); + } + + @Mutation(_returns => Recipe) + async addRecipe(@Arg("recipe") recipe: RecipeInput): Promise { + return this.recipeService.add(recipe); + } + + @FieldResolver() + async numberInCollection(@Root() recipe: Recipe): Promise { + const index = await this.recipeService.findIndex(recipe); + return index + 1; + } +} diff --git a/examples/using-container/recipe-service.ts b/examples/tsyringe/recipe.service.ts similarity index 69% rename from examples/using-container/recipe-service.ts rename to examples/tsyringe/recipe.service.ts index 6272f593d..b20df2ef7 100644 --- a/examples/using-container/recipe-service.ts +++ b/examples/tsyringe/recipe.service.ts @@ -1,13 +1,14 @@ -import { Service, Inject } from "typedi"; +import { inject } from "tsyringe"; +import { type RecipeInput } from "./recipe.input"; +import { Recipe } from "./recipe.type"; -import { Recipe } from "./recipe-type"; -import { RecipeInput } from "./recipe-input"; - -@Service() export class RecipeService { private autoIncrementValue: number; - constructor(@Inject("SAMPLE_RECIPES") private readonly items: Recipe[]) { + constructor( + @inject("SAMPLE_RECIPES") + private readonly items: Recipe[], + ) { this.autoIncrementValue = this.items.length; } @@ -22,6 +23,7 @@ export class RecipeService { async add(data: RecipeInput) { const recipe = this.createRecipe(data); this.items.push(recipe); + return recipe; } @@ -32,10 +34,13 @@ export class RecipeService { private createRecipe(recipeData: Partial): Recipe { const recipe = Object.assign(new Recipe(), recipeData); recipe.id = this.getId(); + return recipe; } private getId(): string { - return (++this.autoIncrementValue).toString(); + this.autoIncrementValue += 1; + + return this.autoIncrementValue.toString(); } } diff --git a/examples/tsyringe/recipe.type.ts b/examples/tsyringe/recipe.type.ts new file mode 100644 index 000000000..d2d0078ad --- /dev/null +++ b/examples/tsyringe/recipe.type.ts @@ -0,0 +1,24 @@ +import { Field, ID, Int, ObjectType } from "type-graphql"; + +@ObjectType() +export class Recipe { + @Field(_type => ID) + id!: string; + + @Field() + title!: string; + + @Field({ nullable: true }) + description?: string; + + @Field(_type => [String]) + ingredients!: string[]; + + @Field(_type => Int) + protected numberInCollection!: number; + + @Field(_type => Int) + protected get ingredientsLength(): number { + return this.ingredients.length; + } +} diff --git a/examples/graphql-modules/schema.gql b/examples/tsyringe/schema.graphql similarity index 52% rename from examples/graphql-modules/schema.gql rename to examples/tsyringe/schema.graphql index d9c672338..efcbbf066 100644 --- a/examples/graphql-modules/schema.gql +++ b/examples/tsyringe/schema.graphql @@ -3,28 +3,26 @@ # !!! DO NOT MODIFY THIS FILE BY YOURSELF !!! # ----------------------------------------------- -""" -The javascript `Date` as string. Type represents date and time as the ISO Date string. -""" -scalar DateTime +type Mutation { + addRecipe(recipe: RecipeInput!): Recipe! +} type Query { + recipe(recipeId: String!): Recipe recipes: [Recipe!]! - users: [User!]! } type Recipe { - author: User! - creationDate: DateTime! description: String - id: Int! + id: ID! + ingredients: [String!]! + ingredientsLength: Int! + numberInCollection: Int! title: String! } -type User { - age: Int! - email: String! - id: Int! - name: String! - recipes: [Recipe!]! +input RecipeInput { + description: String + ingredients: [String!]! + title: String! } diff --git a/examples/typegoose/.env.example b/examples/typegoose/.env.example new file mode 100644 index 000000000..70172d5b3 --- /dev/null +++ b/examples/typegoose/.env.example @@ -0,0 +1 @@ +DATABASE_URL="mongodb://username:password@localhost:27018/type-graphql-example-typegoose" diff --git a/examples/typegoose/context.type.ts b/examples/typegoose/context.type.ts new file mode 100644 index 000000000..c24f7c1b3 --- /dev/null +++ b/examples/typegoose/context.type.ts @@ -0,0 +1,5 @@ +import { type User } from "./entities"; + +export interface Context { + user: User; +} diff --git a/examples/typegoose/entities/index.ts b/examples/typegoose/entities/index.ts new file mode 100644 index 000000000..435b52abf --- /dev/null +++ b/examples/typegoose/entities/index.ts @@ -0,0 +1,3 @@ +export * from "./rating"; +export * from "./recipe"; +export * from "./user"; diff --git a/examples/typegoose/entities/rate.ts b/examples/typegoose/entities/rating.ts similarity index 61% rename from examples/typegoose/entities/rate.ts rename to examples/typegoose/entities/rating.ts index c2dc429f7..97217dbc7 100644 --- a/examples/typegoose/entities/rate.ts +++ b/examples/typegoose/entities/rating.ts @@ -1,20 +1,19 @@ import { prop as Property } from "@typegoose/typegoose"; -import { ObjectType, Field, Int } from "../../../src"; - +import { Field, Int, ObjectType } from "type-graphql"; import { User } from "./user"; import { Ref } from "../types"; @ObjectType() -export class Rate { - @Field(type => Int) +export class Rating { + @Field(_type => Int) @Property({ required: true }) - value: number; + value!: number; @Field() @Property({ default: new Date(), required: true }) - date: Date; + date!: Date; - @Field(type => User) + @Field(_type => User) @Property({ ref: User, required: true }) - user: Ref; + user!: Ref; } diff --git a/examples/typegoose/entities/recipe.ts b/examples/typegoose/entities/recipe.ts index dbd969698..b58a52fab 100644 --- a/examples/typegoose/entities/recipe.ts +++ b/examples/typegoose/entities/recipe.ts @@ -1,31 +1,30 @@ import { prop as Property, getModelForClass } from "@typegoose/typegoose"; -import { ObjectId } from "mongodb"; -import { Field, ObjectType } from "../../../src"; - -import { Rate } from "./rate"; +import { Types } from "mongoose"; +import { Field, ObjectType } from "type-graphql"; +import { Rating } from "./rating"; import { User } from "./user"; import { Ref } from "../types"; @ObjectType() export class Recipe { @Field() - readonly _id: ObjectId; + readonly id!: Types.ObjectId; @Field() @Property({ required: true }) - title: string; + title!: string; @Field({ nullable: true }) @Property() description?: string; - @Field(type => [Rate]) - @Property({ type: () => Rate, default: [] }) - ratings: Rate[]; + @Field(_type => [Rating]) + @Property({ type: () => Rating, default: [] }) + ratings!: Rating[]; - @Field(type => User) + @Field(_type => User) @Property({ ref: User, required: true }) - author: Ref; + author!: Ref; } export const RecipeModel = getModelForClass(Recipe); diff --git a/examples/typegoose/entities/user.ts b/examples/typegoose/entities/user.ts index 30c305885..951a20dbd 100644 --- a/examples/typegoose/entities/user.ts +++ b/examples/typegoose/entities/user.ts @@ -1,22 +1,22 @@ import { prop as Property, getModelForClass } from "@typegoose/typegoose"; -import { ObjectId } from "mongodb"; -import { Field, ObjectType } from "../../../src"; +import { Types } from "mongoose"; +import { Field, ObjectType } from "type-graphql"; @ObjectType() export class User { @Field() - readonly _id: ObjectId; + readonly id!: Types.ObjectId; @Field() @Property({ required: true }) - email: string; + email!: string; @Field({ nullable: true }) @Property() nickname?: string; @Property({ required: true }) - password: string; + password!: string; } export const UserModel = getModelForClass(User); diff --git a/examples/typegoose/examples.gql b/examples/typegoose/examples.graphql similarity index 71% rename from examples/typegoose/examples.gql rename to examples/typegoose/examples.graphql index e3f0a9fd5..5f6cb5090 100644 --- a/examples/typegoose/examples.gql +++ b/examples/typegoose/examples.graphql @@ -12,8 +12,8 @@ query GetRecipes { } query GetRecipe { - # fill with correct ObjectId - recipe(recipeId: "5c97eecbf49a072a00048ac5") { + # Fill with correct ObjectId + recipe(recipeId: "64551384aac388414b391778") { _id title ratings { @@ -43,9 +43,9 @@ mutation AddRecipe { } } -mutation RateRecipe { - # fill with correct ObjectId - rate(rate: { recipeId: "5c97eecbf49a072a00048ac5", value: 4 }) { +mutation RatingRecipe { + # Fill with correct ObjectId + rating(rating: { recipeId: "64557478aac388414b391799", value: 4 }) { _id ratings { value diff --git a/examples/typegoose/helpers.ts b/examples/typegoose/helpers.ts index c092addf8..98d36fcb3 100644 --- a/examples/typegoose/helpers.ts +++ b/examples/typegoose/helpers.ts @@ -1,10 +1,9 @@ -import { Recipe, RecipeModel } from "./entities/recipe"; -import { User, UserModel } from "./entities/user"; +import { RecipeModel, type User, UserModel } from "./entities"; export async function seedDatabase() { const defaultUser = new UserModel({ - email: "test@github.com", - nickname: "MichalLytek", + email: "admin@github.com", + nickname: "administrator", password: "s3cr3tp4ssw0rd", } as User); await defaultUser.save(); @@ -13,24 +12,24 @@ export async function seedDatabase() { { title: "Recipe 1", description: "Desc 1", - author: defaultUser._id, + author: defaultUser.id, ratings: [ - { value: 2, user: defaultUser._id }, - { value: 4, user: defaultUser._id }, - { value: 5, user: defaultUser._id }, - { value: 3, user: defaultUser._id }, - { value: 4, user: defaultUser._id }, + { value: 2, user: defaultUser.id }, + { value: 4, user: defaultUser.id }, + { value: 5, user: defaultUser.id }, + { value: 3, user: defaultUser.id }, + { value: 4, user: defaultUser.id }, ], }, { title: "Recipe 2", - author: defaultUser._id, + author: defaultUser.id, ratings: [ { value: 2, user: defaultUser }, { value: 4, user: defaultUser }, ], }, - ] as Recipe[]); + ]); return { defaultUser }; } diff --git a/examples/typegoose/index.ts b/examples/typegoose/index.ts index 50ee0ef60..811ee0e07 100644 --- a/examples/typegoose/index.ts +++ b/examples/typegoose/index.ts @@ -1,56 +1,50 @@ import "reflect-metadata"; -import { ApolloServer } from "apollo-server"; -import { connect } from "mongoose"; -import { ObjectId } from "mongodb"; -import * as path from "path"; -import { buildSchema } from "../../src"; - -import { RecipeResolver } from "./resolvers/recipe-resolver"; -import { RateResolver } from "./resolvers/rate-resolver"; -import { User } from "./entities/user"; +import "dotenv/config"; +import path from "node:path"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { Types, connect } from "mongoose"; +import { buildSchema } from "type-graphql"; +import { type Context } from "./context.type"; import { seedDatabase } from "./helpers"; -import { TypegooseMiddleware } from "./typegoose-middleware"; import { ObjectIdScalar } from "./object-id.scalar"; - -export interface Context { - user: User; -} - -// replace with your values if needed -const MONGO_DB_URL = "mongodb://localhost:27017/type-graphql"; +import { RatingResolver, RecipeResolver } from "./resolvers"; +import { TypegooseMiddleware } from "./typegoose.middleware"; async function bootstrap() { - try { - // create mongoose connection - const mongoose = await connect(MONGO_DB_URL); - - // clean and seed database with some data - await mongoose.connection.db.dropDatabase(); - const { defaultUser } = await seedDatabase(); - - // build TypeGraphQL executable schema - const schema = await buildSchema({ - resolvers: [RecipeResolver, RateResolver], - emitSchemaFile: path.resolve(__dirname, "schema.gql"), - // use document converting middleware - globalMiddlewares: [TypegooseMiddleware], - // use ObjectId scalar mapping - scalarsMap: [{ type: ObjectId, scalar: ObjectIdScalar }], - validate: false, - }); - - // create mocked context - const context: Context = { user: defaultUser }; - - // Create GraphQL server - const server = new ApolloServer({ schema, context }); - - // Start the server - const { url } = await server.listen(4000); - console.log(`Server is running, GraphQL Playground available at ${url}`); - } catch (err) { - console.error(err); - } + // Create mongoose connection + const mongoose = await connect(process.env.DATABASE_URL!); + + // Clean database + await mongoose.connection.db.dropDatabase(); + // Seed database with some data + const { defaultUser } = await seedDatabase(); + + // Build TypeGraphQL executable schema + const schema = await buildSchema({ + // Array of resolvers + resolvers: [RecipeResolver, RatingResolver], + // Create 'schema.graphql' file with schema definition in current directory + emitSchemaFile: path.resolve(__dirname, "schema.graphql"), + // Use document converting middleware + globalMiddlewares: [TypegooseMiddleware], + // Use ObjectId scalar mapping + scalarsMap: [{ type: Types.ObjectId, scalar: ObjectIdScalar }], + validate: false, + }); + + // Create mocked context + const context: Context = { user: defaultUser }; + + // Create GraphQL server + const server = new ApolloServer({ schema }); + + // Start server + const { url } = await startStandaloneServer(server, { + listen: { port: 4000 }, + context: async () => context, + }); + console.log(`GraphQL server ready at ${url}`); } -bootstrap(); +bootstrap().catch(console.error); diff --git a/examples/typegoose/object-id.scalar.ts b/examples/typegoose/object-id.scalar.ts index 01721104f..40241a565 100644 --- a/examples/typegoose/object-id.scalar.ts +++ b/examples/typegoose/object-id.scalar.ts @@ -1,25 +1,25 @@ import { GraphQLScalarType, Kind } from "graphql"; -import { ObjectId } from "mongodb"; +import { Types } from "mongoose"; export const ObjectIdScalar = new GraphQLScalarType({ name: "ObjectId", description: "Mongo object id scalar type", serialize(value: unknown): string { - if (!(value instanceof ObjectId)) { + if (!(value instanceof Types.ObjectId)) { throw new Error("ObjectIdScalar can only serialize ObjectId values"); } return value.toHexString(); }, - parseValue(value: unknown): ObjectId { + parseValue(value: unknown): Types.ObjectId { if (typeof value !== "string") { throw new Error("ObjectIdScalar can only parse string values"); } - return new ObjectId(value); + return new Types.ObjectId(value); }, - parseLiteral(ast): ObjectId { + parseLiteral(ast): Types.ObjectId { if (ast.kind !== Kind.STRING) { throw new Error("ObjectIdScalar can only parse string values"); } - return new ObjectId(ast.value); + return new Types.ObjectId(ast.value); }, }); diff --git a/examples/typegoose/resolvers/index.ts b/examples/typegoose/resolvers/index.ts new file mode 100644 index 000000000..37d003dee --- /dev/null +++ b/examples/typegoose/resolvers/index.ts @@ -0,0 +1,2 @@ +export * from "./rating.resolver"; +export * from "./recipe.resolver"; diff --git a/examples/typegoose/resolvers/rate-resolver.ts b/examples/typegoose/resolvers/rate-resolver.ts deleted file mode 100644 index 898aa42f5..000000000 --- a/examples/typegoose/resolvers/rate-resolver.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Resolver, FieldResolver, Root } from "../../../src"; - -import { Rate } from "../entities/rate"; -import { User, UserModel } from "../entities/user"; - -@Resolver(of => Rate) -export class RateResolver { - @FieldResolver() - async user(@Root() rate: Rate): Promise { - return (await UserModel.findById(rate.user))!; - } -} diff --git a/examples/typegoose/resolvers/rating.resolver.ts b/examples/typegoose/resolvers/rating.resolver.ts new file mode 100644 index 000000000..fa7005343 --- /dev/null +++ b/examples/typegoose/resolvers/rating.resolver.ts @@ -0,0 +1,10 @@ +import { FieldResolver, Resolver, Root } from "type-graphql"; +import { Rating, type User, UserModel } from "../entities"; + +@Resolver(_of => Rating) +export class RatingResolver { + @FieldResolver() + async user(@Root() rating: Rating): Promise { + return (await UserModel.findById(rating.user))!; + } +} diff --git a/examples/typegoose/resolvers/recipe-resolver.ts b/examples/typegoose/resolvers/recipe-resolver.ts deleted file mode 100644 index 52d0c5e38..000000000 --- a/examples/typegoose/resolvers/recipe-resolver.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { ObjectId } from "mongodb"; -import { Resolver, Query, FieldResolver, Arg, Root, Mutation, Ctx } from "../../../src"; - -import { Recipe, RecipeModel } from "../entities/recipe"; -import { Rate } from "../entities/rate"; -import { User, UserModel } from "../entities/user"; -import { RecipeInput } from "./types/recipe-input"; -import { RateInput } from "./types/rate-input"; -import { Context } from "../index"; -import { ObjectIdScalar } from "../object-id.scalar"; - -@Resolver(of => Recipe) -export class RecipeResolver { - @Query(returns => Recipe, { nullable: true }) - recipe(@Arg("recipeId", type => ObjectIdScalar) recipeId: ObjectId) { - return RecipeModel.findById(recipeId); - } - - @Query(returns => [Recipe]) - async recipes(): Promise { - return await RecipeModel.find({}); - } - - @Mutation(returns => Recipe) - async addRecipe( - @Arg("recipe") recipeInput: RecipeInput, - @Ctx() { user }: Context, - ): Promise { - const recipe = new RecipeModel({ - ...recipeInput, - author: user._id, - } as Recipe); - - await recipe.save(); - return recipe; - } - - @Mutation(returns => Recipe) - async rate(@Arg("rate") rateInput: RateInput, @Ctx() { user }: Context): Promise { - // find the recipe - const recipe = await RecipeModel.findById(rateInput.recipeId); - if (!recipe) { - throw new Error("Invalid recipe ID"); - } - - // set the new recipe rate - const newRate: Rate = { - value: rateInput.value, - user: user._id, - date: new Date(), - }; - - // update the recipe - recipe.ratings.push(newRate); - await recipe.save(); - return recipe; - } - - @FieldResolver() - async author(@Root() recipe: Recipe): Promise { - return (await UserModel.findById(recipe.author))!; - } -} diff --git a/examples/typegoose/resolvers/recipe.resolver.ts b/examples/typegoose/resolvers/recipe.resolver.ts new file mode 100644 index 000000000..74ddba900 --- /dev/null +++ b/examples/typegoose/resolvers/recipe.resolver.ts @@ -0,0 +1,61 @@ +import { Types } from "mongoose"; +import { Arg, Ctx, FieldResolver, Mutation, Query, Resolver, Root } from "type-graphql"; +import { RatingInput, RecipeInput } from "./types"; +import { Context } from "../context.type"; +import { type Rating, Recipe, RecipeModel, type User, UserModel } from "../entities"; +import { ObjectIdScalar } from "../object-id.scalar"; + +@Resolver(_of => Recipe) +export class RecipeResolver { + @Query(_returns => Recipe, { nullable: true }) + recipe(@Arg("recipeId", () => ObjectIdScalar) recipeId: Types.ObjectId) { + return RecipeModel.findById(recipeId); + } + + @Query(_returns => [Recipe]) + async recipes(): Promise { + return RecipeModel.find({}); + } + + @Mutation(_returns => Recipe) + async addRecipe( + @Arg("recipe") recipeInput: RecipeInput, + @Ctx() { user }: Context, + ): Promise { + const recipe = new RecipeModel({ + ...recipeInput, + author: user.id, + }); + + await recipe.save(); + + return recipe; + } + + @Mutation(_returns => Recipe) + async rating(@Arg("rating") ratingInput: RatingInput, @Ctx() { user }: Context): Promise { + // Find the recipe + const recipe = await RecipeModel.findById(ratingInput.recipeId); + if (!recipe) { + throw new Error("Invalid recipe ID"); + } + + // Set the new recipe rating + const newRating: Rating = { + value: ratingInput.value, + user: user.id, + date: new Date(), + }; + + // Add and update the new recipe + recipe.ratings.push(newRating); + await recipe.save(); + + return recipe; + } + + @FieldResolver() + async author(@Root() recipe: Recipe): Promise { + return (await UserModel.findById(recipe.author))!; + } +} diff --git a/examples/typegoose/resolvers/types/index.ts b/examples/typegoose/resolvers/types/index.ts new file mode 100644 index 000000000..0538b5ca4 --- /dev/null +++ b/examples/typegoose/resolvers/types/index.ts @@ -0,0 +1,2 @@ +export * from "./rating.input"; +export * from "./recipe.input"; diff --git a/examples/typegoose/resolvers/types/rate-input.ts b/examples/typegoose/resolvers/types/rate-input.ts deleted file mode 100644 index 8674368f2..000000000 --- a/examples/typegoose/resolvers/types/rate-input.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { ObjectId } from "mongodb"; -import { InputType, Field, Int } from "../../../../src"; - -@InputType() -export class RateInput { - @Field() - recipeId: ObjectId; - - @Field(type => Int) - value: number; -} diff --git a/examples/typegoose/resolvers/types/rating.input.ts b/examples/typegoose/resolvers/types/rating.input.ts new file mode 100644 index 000000000..a4c4cdc61 --- /dev/null +++ b/examples/typegoose/resolvers/types/rating.input.ts @@ -0,0 +1,11 @@ +import { Types } from "mongoose"; +import { Field, InputType, Int } from "type-graphql"; + +@InputType() +export class RatingInput { + @Field() + recipeId!: Types.ObjectId; + + @Field(_type => Int) + value!: number; +} diff --git a/examples/typeorm-basic-usage/resolvers/types/recipe-input.ts b/examples/typegoose/resolvers/types/recipe.input.ts similarity index 53% rename from examples/typeorm-basic-usage/resolvers/types/recipe-input.ts rename to examples/typegoose/resolvers/types/recipe.input.ts index b2c157c91..5a75d4cb8 100644 --- a/examples/typeorm-basic-usage/resolvers/types/recipe-input.ts +++ b/examples/typegoose/resolvers/types/recipe.input.ts @@ -1,11 +1,10 @@ -import { InputType, Field } from "../../../../src"; - -import { Recipe } from "../../entities/recipe"; +import { Field, InputType } from "type-graphql"; +import { type Recipe } from "../../entities"; @InputType() export class RecipeInput implements Partial { @Field() - title: string; + title!: string; @Field({ nullable: true }) description?: string; diff --git a/examples/typegoose/schema.gql b/examples/typegoose/schema.graphql similarity index 53% rename from examples/typegoose/schema.gql rename to examples/typegoose/schema.graphql index 25561bb10..610aad720 100644 --- a/examples/typegoose/schema.gql +++ b/examples/typegoose/schema.graphql @@ -4,16 +4,18 @@ # ----------------------------------------------- """ -The javascript `Date` as string. Type represents date and time as the ISO Date string. +A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar.This scalar is serialized to a string in ISO 8601 format and parsed from a string in ISO 8601 format. """ -scalar DateTime +scalar DateTimeISO type Mutation { addRecipe(recipe: RecipeInput!): Recipe! - rate(rate: RateInput!): Recipe! + rating(rating: RatingInput!): Recipe! } -"""Mongo object id scalar type""" +""" +Mongo object id scalar type +""" scalar ObjectId type Query { @@ -21,22 +23,22 @@ type Query { recipes: [Recipe!]! } -type Rate { - date: DateTime! +type Rating { + date: DateTimeISO! user: User! value: Int! } -input RateInput { +input RatingInput { recipeId: ObjectId! value: Int! } type Recipe { - _id: ObjectId! author: User! description: String - ratings: [Rate!]! + id: ObjectId! + ratings: [Rating!]! title: String! } @@ -46,7 +48,7 @@ input RecipeInput { } type User { - _id: ObjectId! email: String! + id: ObjectId! nickname: String } diff --git a/examples/typegoose/typegoose-middleware.ts b/examples/typegoose/typegoose.middleware.ts similarity index 71% rename from examples/typegoose/typegoose-middleware.ts rename to examples/typegoose/typegoose.middleware.ts index bec6d2a6e..24fa3e0e0 100644 --- a/examples/typegoose/typegoose-middleware.ts +++ b/examples/typegoose/typegoose.middleware.ts @@ -1,6 +1,13 @@ -import { Model, Document } from "mongoose"; -import { getClassForDocument } from "@typegoose/typegoose"; -import { MiddlewareFn } from "../../src"; +import { getClass } from "@typegoose/typegoose"; +import { type Document, Model } from "mongoose"; +import { type MiddlewareFn } from "type-graphql"; + +function convertDocument(doc: Document) { + const convertedDocument = doc.toObject(); + const DocumentClass = getClass(doc)!; + Object.setPrototypeOf(convertedDocument, DocumentClass.prototype); + return convertedDocument; +} export const TypegooseMiddleware: MiddlewareFn = async (_, next) => { const result = await next(); @@ -15,10 +22,3 @@ export const TypegooseMiddleware: MiddlewareFn = async (_, next) => { return result; }; - -function convertDocument(doc: Document) { - const convertedDocument = doc.toObject(); - const DocumentClass = getClassForDocument(doc)!; - Object.setPrototypeOf(convertedDocument, DocumentClass.prototype); - return convertedDocument; -} diff --git a/examples/typegoose/types.ts b/examples/typegoose/types.ts index 13aeebf83..1d52cb1d6 100644 --- a/examples/typegoose/types.ts +++ b/examples/typegoose/types.ts @@ -1,3 +1,3 @@ -import { ObjectId } from "mongodb"; +import { type Types } from "mongoose"; -export type Ref = T | ObjectId; +export type Ref = T | Types.ObjectId; diff --git a/examples/typeorm-basic-usage/.env.example b/examples/typeorm-basic-usage/.env.example new file mode 100644 index 000000000..87b78ab85 --- /dev/null +++ b/examples/typeorm-basic-usage/.env.example @@ -0,0 +1 @@ +DATABASE_URL="postgresql://username:password@localhost:5432/type-graphql-example-typeorm-basic" diff --git a/examples/typeorm-basic-usage/context.type.ts b/examples/typeorm-basic-usage/context.type.ts new file mode 100644 index 000000000..c24f7c1b3 --- /dev/null +++ b/examples/typeorm-basic-usage/context.type.ts @@ -0,0 +1,5 @@ +import { type User } from "./entities"; + +export interface Context { + user: User; +} diff --git a/examples/typeorm-basic-usage/datasource.ts b/examples/typeorm-basic-usage/datasource.ts new file mode 100644 index 000000000..8c6ed71b6 --- /dev/null +++ b/examples/typeorm-basic-usage/datasource.ts @@ -0,0 +1,14 @@ +import * as TypeORM from "typeorm"; +import { Rating, Recipe, User } from "./entities"; + +// Create TypeORM dataSource +export const dataSource = new TypeORM.DataSource({ + type: "postgres", + url: process.env.DATABASE_URL, + synchronize: true, + dropSchema: true, + cache: true, + logging: "all", + entities: [Rating, Recipe, User], + logger: "advanced-console", +}); diff --git a/examples/typeorm-basic-usage/entities/index.ts b/examples/typeorm-basic-usage/entities/index.ts new file mode 100644 index 000000000..435b52abf --- /dev/null +++ b/examples/typeorm-basic-usage/entities/index.ts @@ -0,0 +1,3 @@ +export * from "./rating"; +export * from "./recipe"; +export * from "./user"; diff --git a/examples/typeorm-basic-usage/entities/rate.ts b/examples/typeorm-basic-usage/entities/rate.ts deleted file mode 100644 index 10c4d3294..000000000 --- a/examples/typeorm-basic-usage/entities/rate.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ObjectType, Field, Int } from "../../../src"; -import { - Column, - Entity, - ManyToOne, - PrimaryGeneratedColumn, - CreateDateColumn, - RelationId, -} from "typeorm"; - -import { User } from "./user"; -import { Recipe } from "./recipe"; - -@Entity() -@ObjectType() -export class Rate { - @PrimaryGeneratedColumn() - readonly id: number; - - @Field(type => Int) - @Column({ type: "int" }) - value: number; - - @Field(type => User) - @ManyToOne(type => User) - user: User; - @RelationId((rate: Rate) => rate.user) - userId: number; - - @Field() - @CreateDateColumn() - date: Date; - - @ManyToOne(type => Recipe) - recipe: Recipe; - @RelationId((rate: Rate) => rate.recipe) - recipeId: number; -} diff --git a/examples/typeorm-basic-usage/entities/rating.ts b/examples/typeorm-basic-usage/entities/rating.ts new file mode 100644 index 000000000..b19a2da14 --- /dev/null +++ b/examples/typeorm-basic-usage/entities/rating.ts @@ -0,0 +1,39 @@ +import { Field, Int, ObjectType } from "type-graphql"; +import { + Column, + CreateDateColumn, + Entity, + ManyToOne, + PrimaryGeneratedColumn, + RelationId, +} from "typeorm"; +import { Recipe } from "./recipe"; +import { User } from "./user"; + +@Entity() +@ObjectType() +export class Rating { + @PrimaryGeneratedColumn() + readonly id!: number; + + @Field(_type => Int) + @Column({ type: "int" }) + value!: number; + + @Field(_type => User) + @ManyToOne(_type => User) + user!: User; + + @RelationId((rating: Rating) => rating.user) + userId!: number; + + @Field() + @CreateDateColumn() + date!: Date; + + @ManyToOne(_type => Recipe) + recipe!: Recipe; + + @RelationId((rating: Rating) => rating.recipe) + recipeId!: number; +} diff --git a/examples/typeorm-basic-usage/entities/recipe.ts b/examples/typeorm-basic-usage/entities/recipe.ts index 77293e365..cc205bd14 100644 --- a/examples/typeorm-basic-usage/entities/recipe.ts +++ b/examples/typeorm-basic-usage/entities/recipe.ts @@ -1,31 +1,31 @@ -import { Field, ID, ObjectType } from "../../../src"; -import { Entity, PrimaryGeneratedColumn, Column, OneToMany, ManyToOne, RelationId } from "typeorm"; - -import { Rate } from "./rate"; +import { Field, ID, ObjectType } from "type-graphql"; +import { Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn, RelationId } from "typeorm"; +import { Rating } from "./rating"; import { User } from "./user"; @Entity() @ObjectType() export class Recipe { - @Field(type => ID) + @Field(_type => ID) @PrimaryGeneratedColumn() - readonly id: number; + readonly id!: number; @Field() @Column() - title: string; + title!: string; @Field({ nullable: true }) @Column({ nullable: true }) description?: string; - @Field(type => [Rate]) - @OneToMany(type => Rate, rate => rate.recipe, { cascade: ["insert"] }) - ratings: Rate[]; + @Field(_type => [Rating]) + @OneToMany(_type => Rating, rating => rating.recipe, { cascade: ["insert"] }) + ratings!: Rating[]; + + @Field(_type => User) + @ManyToOne(_type => User) + author!: User; - @Field(type => User) - @ManyToOne(type => User) - author: User; @RelationId((recipe: Recipe) => recipe.author) - authorId: number; + authorId!: number; } diff --git a/examples/typeorm-basic-usage/entities/user.ts b/examples/typeorm-basic-usage/entities/user.ts index b2f3b206f..b38bdb589 100644 --- a/examples/typeorm-basic-usage/entities/user.ts +++ b/examples/typeorm-basic-usage/entities/user.ts @@ -1,21 +1,21 @@ -import { Field, ID, ObjectType } from "../../../src"; -import { PrimaryGeneratedColumn, Column, Entity } from "typeorm"; +import { Field, ID, ObjectType } from "type-graphql"; +import { Column, Entity, PrimaryGeneratedColumn } from "typeorm"; @ObjectType() @Entity() export class User { - @Field(type => ID) + @Field(_type => ID) @PrimaryGeneratedColumn() - readonly id: number; + readonly id!: number; @Field() @Column() - email: string; + email!: string; @Field({ nullable: true }) @Column({ nullable: true }) nickname?: string; @Column() - password: string; + password!: string; } diff --git a/examples/mikro-orm/examples.gql b/examples/typeorm-basic-usage/examples.graphql similarity index 79% rename from examples/mikro-orm/examples.gql rename to examples/typeorm-basic-usage/examples.graphql index 424e0bc4a..417a71bca 100644 --- a/examples/mikro-orm/examples.gql +++ b/examples/typeorm-basic-usage/examples.graphql @@ -31,9 +31,7 @@ query GetRecipe { } mutation AddRecipe { - addRecipe(recipe: { - title: "New Recipe" - }) { + addRecipe(recipe: { title: "New Recipe" }) { id ratings { value @@ -44,11 +42,8 @@ mutation AddRecipe { } } -mutation RateRecipe { - rate(rate: { - recipeId: 3 - value: 4 - }) { +mutation RatingRecipe { + rating(rating: { recipeId: 3, value: 4 }) { id ratings { value diff --git a/examples/typeorm-basic-usage/helpers.ts b/examples/typeorm-basic-usage/helpers.ts index 3afa81ff3..3f0d0e5e4 100644 --- a/examples/typeorm-basic-usage/helpers.ts +++ b/examples/typeorm-basic-usage/helpers.ts @@ -1,17 +1,14 @@ -import { getRepository } from "typeorm"; - -import { Recipe } from "./entities/recipe"; -import { Rate } from "./entities/rate"; -import { User } from "./entities/user"; +import { dataSource } from "./datasource"; +import { Rating, Recipe, User } from "./entities"; export async function seedDatabase() { - const recipeRepository = getRepository(Recipe); - const ratingsRepository = getRepository(Rate); - const userRepository = getRepository(User); + const recipeRepository = dataSource.getRepository(Recipe); + const ratingRepository = dataSource.getRepository(Rating); + const userRepository = dataSource.getRepository(User); const defaultUser = userRepository.create({ - email: "test@github.com", - nickname: "MichalLytek", + email: "admin@github.com", + nickname: "administrator", password: "s3cr3tp4ssw0rd", }); await userRepository.save(defaultUser); @@ -21,7 +18,7 @@ export async function seedDatabase() { title: "Recipe 1", description: "Desc 1", author: defaultUser, - ratings: ratingsRepository.create([ + ratings: ratingRepository.create([ { value: 2, user: defaultUser }, { value: 4, user: defaultUser }, { value: 5, user: defaultUser }, @@ -32,7 +29,7 @@ export async function seedDatabase() { { title: "Recipe 2", author: defaultUser, - ratings: ratingsRepository.create([ + ratings: ratingRepository.create([ { value: 2, user: defaultUser }, { value: 4, user: defaultUser }, ]), diff --git a/examples/typeorm-basic-usage/index.ts b/examples/typeorm-basic-usage/index.ts index ed0dd3a13..a98eefb98 100644 --- a/examples/typeorm-basic-usage/index.ts +++ b/examples/typeorm-basic-usage/index.ts @@ -1,62 +1,41 @@ import "reflect-metadata"; -import { ApolloServer } from "apollo-server"; -import { Container } from "typedi"; -import * as TypeORM from "typeorm"; -import * as TypeGraphQL from "../../src"; - -import { RecipeResolver } from "./resolvers/recipe-resolver"; -import { RateResolver } from "./resolvers/rate-resolver"; -import { Recipe } from "./entities/recipe"; -import { Rate } from "./entities/rate"; -import { User } from "./entities/user"; +import "dotenv/config"; +import path from "node:path"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { buildSchema } from "type-graphql"; +import { type Context } from "./context.type"; +import { dataSource } from "./datasource"; import { seedDatabase } from "./helpers"; - -export interface Context { - user: User; -} - -// register 3rd party IOC container -TypeORM.useContainer(Container); +import { RatingResolver, RecipeResolver } from "./resolvers"; async function bootstrap() { - try { - // create TypeORM connection - await TypeORM.createConnection({ - type: "postgres", - database: "type-graphql-basic", - username: "postgres", // fill this with your username - password: "qwerty", // and password - port: 5434, // and port - host: "localhost", // and host - entities: [Recipe, Rate, User], - synchronize: true, - logger: "advanced-console", - logging: "all", - dropSchema: true, - cache: true, - }); - - // seed database with some data - const { defaultUser } = await seedDatabase(); - - // build TypeGraphQL executable schema - const schema = await TypeGraphQL.buildSchema({ - resolvers: [RecipeResolver, RateResolver], - container: Container, - }); - - // create mocked context - const context: Context = { user: defaultUser }; - - // Create GraphQL server - const server = new ApolloServer({ schema, context }); - - // Start the server - const { url } = await server.listen(4000); - console.log(`Server is running, GraphQL Playground available at ${url}`); - } catch (err) { - console.error(err); - } + // Create TypeORM connection + await dataSource.initialize(); + + // Seed database with some data + const { defaultUser } = await seedDatabase(); + + // Build TypeGraphQL executable schema + const schema = await buildSchema({ + // Array of resolvers + resolvers: [RecipeResolver, RatingResolver], + // Create 'schema.graphql' file with schema definition in current directory + emitSchemaFile: path.resolve(__dirname, "schema.graphql"), + }); + + // Create mocked context + const context: Context = { user: defaultUser }; + + // Create GraphQL server + const server = new ApolloServer({ schema }); + + // Start server + const { url } = await startStandaloneServer(server, { + listen: { port: 4000 }, + context: async () => context, + }); + console.log(`GraphQL server ready at ${url}`); } -bootstrap(); +bootstrap().catch(console.error); diff --git a/examples/typeorm-basic-usage/resolvers/index.ts b/examples/typeorm-basic-usage/resolvers/index.ts new file mode 100644 index 000000000..37d003dee --- /dev/null +++ b/examples/typeorm-basic-usage/resolvers/index.ts @@ -0,0 +1,2 @@ +export * from "./rating.resolver"; +export * from "./recipe.resolver"; diff --git a/examples/typeorm-basic-usage/resolvers/rate-resolver.ts b/examples/typeorm-basic-usage/resolvers/rate-resolver.ts deleted file mode 100644 index b4dfe39ee..000000000 --- a/examples/typeorm-basic-usage/resolvers/rate-resolver.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Resolver, FieldResolver, Root } from "../../../src"; -import { Repository } from "typeorm"; -import { InjectRepository } from "typeorm-typedi-extensions"; - -import { Rate } from "../entities/rate"; -import { User } from "../entities/user"; - -@Resolver(of => Rate) -export class RateResolver { - constructor(@InjectRepository(User) private readonly userRepository: Repository) {} - - @FieldResolver() - async user(@Root() rate: Rate): Promise { - return (await this.userRepository.findOne(rate.userId, { cache: 1000 }))!; - } -} diff --git a/examples/typeorm-basic-usage/resolvers/rating.resolver.ts b/examples/typeorm-basic-usage/resolvers/rating.resolver.ts new file mode 100644 index 000000000..4f3a54ce9 --- /dev/null +++ b/examples/typeorm-basic-usage/resolvers/rating.resolver.ts @@ -0,0 +1,18 @@ +import { FieldResolver, Resolver, Root } from "type-graphql"; +import { type Repository } from "typeorm"; +import { dataSource } from "../datasource"; +import { Rating, User } from "../entities"; + +@Resolver(_of => Rating) +export class RatingResolver { + private readonly userRepository: Repository; + + constructor() { + this.userRepository = dataSource.getRepository(User); + } + + @FieldResolver() + async user(@Root() rating: Rating): Promise { + return (await this.userRepository.findOne({ where: { id: rating.userId }, cache: 1000 }))!; + } +} diff --git a/examples/typeorm-basic-usage/resolvers/recipe-resolver.ts b/examples/typeorm-basic-usage/resolvers/recipe-resolver.ts deleted file mode 100644 index dad3741dc..000000000 --- a/examples/typeorm-basic-usage/resolvers/recipe-resolver.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { Resolver, Query, FieldResolver, Arg, Root, Mutation, Ctx, Int } from "../../../src"; -import { Repository } from "typeorm"; -import { InjectRepository } from "typeorm-typedi-extensions"; - -import { Recipe } from "../entities/recipe"; -import { Rate } from "../entities/rate"; -import { User } from "../entities/user"; -import { RecipeInput } from "./types/recipe-input"; -import { Context } from "../index"; -import { RateInput } from "./types/rate-input"; - -@Resolver(of => Recipe) -export class RecipeResolver { - constructor( - @InjectRepository(Recipe) private readonly recipeRepository: Repository, - @InjectRepository(Rate) private readonly ratingsRepository: Repository, - @InjectRepository(User) private readonly userRepository: Repository, - ) {} - - @Query(returns => Recipe, { nullable: true }) - recipe(@Arg("recipeId", type => Int) recipeId: number) { - return this.recipeRepository.findOne(recipeId); - } - - @Query(returns => [Recipe]) - recipes(): Promise { - return this.recipeRepository.find(); - } - - @Mutation(returns => Recipe) - async addRecipe( - @Arg("recipe") recipeInput: RecipeInput, - @Ctx() { user }: Context, - ): Promise { - const recipe = this.recipeRepository.create({ - ...recipeInput, - authorId: user.id, - }); - return await this.recipeRepository.save(recipe); - } - - @Mutation(returns => Recipe) - async rate(@Arg("rate") rateInput: RateInput, @Ctx() { user }: Context): Promise { - // find the recipe - const recipe = await this.recipeRepository.findOne(rateInput.recipeId, { - relations: ["ratings"], - }); - if (!recipe) { - throw new Error("Invalid recipe ID"); - } - - // set the new recipe rate - const newRate = this.ratingsRepository.create({ - recipe, - value: rateInput.value, - user, - }); - recipe.ratings.push(newRate); - - // update the recipe - await this.recipeRepository.save(recipe); - return recipe; - } - - @FieldResolver() - ratings(@Root() recipe: Recipe) { - return this.ratingsRepository.find({ - cache: 1000, - where: { recipe: { id: recipe.id } }, - }); - } - - @FieldResolver() - async author(@Root() recipe: Recipe): Promise { - return (await this.userRepository.findOne(recipe.authorId, { cache: 1000 }))!; - } -} diff --git a/examples/typeorm-basic-usage/resolvers/recipe.resolver.ts b/examples/typeorm-basic-usage/resolvers/recipe.resolver.ts new file mode 100644 index 000000000..c88220584 --- /dev/null +++ b/examples/typeorm-basic-usage/resolvers/recipe.resolver.ts @@ -0,0 +1,80 @@ +import { Arg, Ctx, FieldResolver, Int, Mutation, Query, Resolver, Root } from "type-graphql"; +import { type Repository } from "typeorm"; +import { RatingInput, RecipeInput } from "./types"; +import { Context } from "../context.type"; +import { dataSource } from "../datasource"; +import { Rating, Recipe, User } from "../entities"; + +@Resolver(_of => Recipe) +export class RecipeResolver { + private readonly ratingRepository: Repository; + + private readonly recipeRepository: Repository; + + private readonly userRepository: Repository; + + constructor() { + this.ratingRepository = dataSource.getRepository(Rating); + this.recipeRepository = dataSource.getRepository(Recipe); + this.userRepository = dataSource.getRepository(User); + } + + @Query(_returns => Recipe, { nullable: true }) + recipe(@Arg("recipeId", _type => Int) recipeId: number) { + return this.recipeRepository.findOneBy({ id: recipeId }); + } + + @Query(_returns => [Recipe]) + recipes(): Promise { + return this.recipeRepository.find(); + } + + @Mutation(_returns => Recipe) + async addRecipe( + @Arg("recipe") recipeInput: RecipeInput, + @Ctx() { user }: Context, + ): Promise { + const recipe = this.recipeRepository.create({ + ...recipeInput, + authorId: user.id, + }); + return this.recipeRepository.save(recipe); + } + + @Mutation(_returns => Recipe) + async rating(@Arg("rating") ratingInput: RatingInput, @Ctx() { user }: Context): Promise { + // Find the recipe + const recipe = await this.recipeRepository.findOne({ + where: { id: ratingInput.recipeId }, + relations: ["ratings"], + }); + if (!recipe) { + throw new Error("Invalid recipe ID"); + } + + // Set the new recipe rating + const newRating = this.ratingRepository.create({ + recipe, + value: ratingInput.value, + user, + }); + + recipe.ratings.push(newRating); + + // Update and return recipe + return this.recipeRepository.save(recipe); + } + + @FieldResolver() + ratings(@Root() recipe: Recipe) { + return this.ratingRepository.find({ + cache: 1000, + where: { recipe: { id: recipe.id } }, + }); + } + + @FieldResolver() + async author(@Root() recipe: Recipe): Promise { + return (await this.userRepository.findOne({ where: { id: recipe.authorId }, cache: 1000 }))!; + } +} diff --git a/examples/typeorm-basic-usage/resolvers/types/index.ts b/examples/typeorm-basic-usage/resolvers/types/index.ts new file mode 100644 index 000000000..0538b5ca4 --- /dev/null +++ b/examples/typeorm-basic-usage/resolvers/types/index.ts @@ -0,0 +1,2 @@ +export * from "./rating.input"; +export * from "./recipe.input"; diff --git a/examples/typeorm-basic-usage/resolvers/types/rate-input.ts b/examples/typeorm-basic-usage/resolvers/types/rate-input.ts deleted file mode 100644 index e8fb38e12..000000000 --- a/examples/typeorm-basic-usage/resolvers/types/rate-input.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { InputType, Field, Int, ID } from "../../../../src"; - -@InputType() -export class RateInput { - @Field(type => ID) - recipeId: string; - - @Field(type => Int) - value: number; -} diff --git a/examples/typeorm-basic-usage/resolvers/types/rating.input.ts b/examples/typeorm-basic-usage/resolvers/types/rating.input.ts new file mode 100644 index 000000000..cdff2e505 --- /dev/null +++ b/examples/typeorm-basic-usage/resolvers/types/rating.input.ts @@ -0,0 +1,10 @@ +import { Field, InputType, Int } from "type-graphql"; + +@InputType() +export class RatingInput { + @Field(_type => Int) + recipeId!: number; + + @Field(_type => Int) + value!: number; +} diff --git a/examples/typegoose/resolvers/types/recipe-input.ts b/examples/typeorm-basic-usage/resolvers/types/recipe.input.ts similarity index 53% rename from examples/typegoose/resolvers/types/recipe-input.ts rename to examples/typeorm-basic-usage/resolvers/types/recipe.input.ts index b2c157c91..5a75d4cb8 100644 --- a/examples/typegoose/resolvers/types/recipe-input.ts +++ b/examples/typeorm-basic-usage/resolvers/types/recipe.input.ts @@ -1,11 +1,10 @@ -import { InputType, Field } from "../../../../src"; - -import { Recipe } from "../../entities/recipe"; +import { Field, InputType } from "type-graphql"; +import { type Recipe } from "../../entities"; @InputType() export class RecipeInput implements Partial { @Field() - title: string; + title!: string; @Field({ nullable: true }) description?: string; diff --git a/examples/typeorm-basic-usage/schema.graphql b/examples/typeorm-basic-usage/schema.graphql new file mode 100644 index 000000000..fe2abd744 --- /dev/null +++ b/examples/typeorm-basic-usage/schema.graphql @@ -0,0 +1,49 @@ +# ----------------------------------------------- +# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!! +# !!! DO NOT MODIFY THIS FILE BY YOURSELF !!! +# ----------------------------------------------- + +""" +A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar.This scalar is serialized to a string in ISO 8601 format and parsed from a string in ISO 8601 format. +""" +scalar DateTimeISO + +type Mutation { + addRecipe(recipe: RecipeInput!): Recipe! + rating(rating: RatingInput!): Recipe! +} + +type Query { + recipe(recipeId: Int!): Recipe + recipes: [Recipe!]! +} + +type Rating { + date: DateTimeISO! + user: User! + value: Int! +} + +input RatingInput { + recipeId: Int! + value: Int! +} + +type Recipe { + author: User! + description: String + id: ID! + ratings: [Rating!]! + title: String! +} + +input RecipeInput { + description: String + title: String! +} + +type User { + email: String! + id: ID! + nickname: String +} diff --git a/examples/typeorm-lazy-relations/.env.example b/examples/typeorm-lazy-relations/.env.example new file mode 100644 index 000000000..d192c5d0f --- /dev/null +++ b/examples/typeorm-lazy-relations/.env.example @@ -0,0 +1 @@ +DATABASE_URL="postgresql://username:password@localhost:5432/type-graphql-example-typeorm-lazy" diff --git a/examples/typeorm-lazy-relations/context.type.ts b/examples/typeorm-lazy-relations/context.type.ts new file mode 100644 index 000000000..c24f7c1b3 --- /dev/null +++ b/examples/typeorm-lazy-relations/context.type.ts @@ -0,0 +1,5 @@ +import { type User } from "./entities"; + +export interface Context { + user: User; +} diff --git a/examples/typeorm-lazy-relations/datasource.ts b/examples/typeorm-lazy-relations/datasource.ts new file mode 100644 index 000000000..8c6ed71b6 --- /dev/null +++ b/examples/typeorm-lazy-relations/datasource.ts @@ -0,0 +1,14 @@ +import * as TypeORM from "typeorm"; +import { Rating, Recipe, User } from "./entities"; + +// Create TypeORM dataSource +export const dataSource = new TypeORM.DataSource({ + type: "postgres", + url: process.env.DATABASE_URL, + synchronize: true, + dropSchema: true, + cache: true, + logging: "all", + entities: [Rating, Recipe, User], + logger: "advanced-console", +}); diff --git a/examples/typeorm-lazy-relations/entities/index.ts b/examples/typeorm-lazy-relations/entities/index.ts new file mode 100644 index 000000000..435b52abf --- /dev/null +++ b/examples/typeorm-lazy-relations/entities/index.ts @@ -0,0 +1,3 @@ +export * from "./rating"; +export * from "./recipe"; +export * from "./user"; diff --git a/examples/typeorm-lazy-relations/entities/rate.ts b/examples/typeorm-lazy-relations/entities/rate.ts deleted file mode 100644 index f494e5654..000000000 --- a/examples/typeorm-lazy-relations/entities/rate.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ObjectType, Field, Int } from "../../../src"; -import { Column, Entity, ManyToOne, PrimaryGeneratedColumn, CreateDateColumn } from "typeorm"; - -import { User } from "./user"; -import { Recipe } from "./recipe"; -import { Lazy } from "../helpers"; - -@Entity() -@ObjectType() -export class Rate { - @PrimaryGeneratedColumn() - readonly id: number; - - @Field(type => Int) - @Column({ type: "int" }) - value: number; - - @Field(type => User) - @ManyToOne(type => User, { lazy: true }) - user: Lazy; - - @Field() - @CreateDateColumn() - date: Date; - - @ManyToOne(type => Recipe, { lazy: true }) - recipe: Lazy; -} diff --git a/examples/typeorm-lazy-relations/entities/rating.ts b/examples/typeorm-lazy-relations/entities/rating.ts new file mode 100644 index 000000000..bda52f66d --- /dev/null +++ b/examples/typeorm-lazy-relations/entities/rating.ts @@ -0,0 +1,26 @@ +import { Field, Int, ObjectType } from "type-graphql"; +import { Column, CreateDateColumn, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { Recipe } from "./recipe"; +import { User } from "./user"; + +@Entity() +@ObjectType() +export class Rating { + @PrimaryGeneratedColumn() + readonly id!: number; + + @Field(_type => Int) + @Column({ type: "int" }) + value!: number; + + @Field(_type => User) + @ManyToOne(_type => User, { lazy: true }) + user!: User | Promise; + + @Field() + @CreateDateColumn() + date!: Date; + + @ManyToOne(_type => Recipe, { lazy: true }) + recipe!: Recipe | Promise; +} diff --git a/examples/typeorm-lazy-relations/entities/recipe.ts b/examples/typeorm-lazy-relations/entities/recipe.ts index 7211e7bc2..082846c5b 100644 --- a/examples/typeorm-lazy-relations/entities/recipe.ts +++ b/examples/typeorm-lazy-relations/entities/recipe.ts @@ -1,30 +1,28 @@ -import { Field, ID, ObjectType } from "../../../src"; -import { Entity, PrimaryGeneratedColumn, Column, OneToMany, ManyToOne } from "typeorm"; - -import { Rate } from "./rate"; +import { Field, ID, ObjectType } from "type-graphql"; +import { Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm"; +import { Rating } from "./rating"; import { User } from "./user"; -import { Lazy } from "../helpers"; @Entity() @ObjectType() export class Recipe { - @Field(type => ID) + @Field(_type => ID) @PrimaryGeneratedColumn() - readonly id: number; + readonly id!: number; @Field() @Column() - title: string; + title!: string; @Field({ nullable: true }) @Column({ nullable: true }) description?: string; - @Field(type => [Rate]) - @OneToMany(type => Rate, rate => rate.recipe, { lazy: true, cascade: ["insert"] }) - ratings: Lazy; + @Field(_type => [Rating]) + @OneToMany(_type => Rating, rating => rating.recipe, { lazy: true, cascade: ["insert"] }) + ratings!: Rating[] | Promise; - @Field(type => User) - @ManyToOne(type => User, { lazy: true }) - author: Lazy; + @Field(_type => User) + @ManyToOne(_type => User, { lazy: true }) + author!: User | Promise; } diff --git a/examples/typeorm-lazy-relations/entities/user.ts b/examples/typeorm-lazy-relations/entities/user.ts index e21a5c0b4..8e89c011d 100644 --- a/examples/typeorm-lazy-relations/entities/user.ts +++ b/examples/typeorm-lazy-relations/entities/user.ts @@ -1,28 +1,26 @@ -import { Field, ID, ObjectType } from "../../../src"; -import { PrimaryGeneratedColumn, Column, Entity, OneToMany } from "typeorm"; - +import { Field, ID, ObjectType } from "type-graphql"; +import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm"; import { Recipe } from "./recipe"; -import { Lazy } from "../helpers"; @ObjectType() @Entity() export class User { - @Field(type => ID) + @Field(_type => ID) @PrimaryGeneratedColumn() - readonly id: number; + readonly id!: number; @Field() @Column() - email: string; + email!: string; @Field({ nullable: true }) @Column({ nullable: true }) nickname?: string; @Column() - password: string; + password!: string; - @OneToMany(type => Recipe, recipe => recipe.author, { lazy: true }) - @Field(type => [Recipe]) - recipes: Lazy; + @OneToMany(_type => Recipe, recipe => recipe.author, { lazy: true }) + @Field(_type => [Recipe]) + recipes!: Recipe[] | Promise; } diff --git a/examples/typeorm-lazy-relations/examples.gql b/examples/typeorm-lazy-relations/examples.graphql similarity index 80% rename from examples/typeorm-lazy-relations/examples.gql rename to examples/typeorm-lazy-relations/examples.graphql index b14efabe4..2f845e12f 100644 --- a/examples/typeorm-lazy-relations/examples.gql +++ b/examples/typeorm-lazy-relations/examples.graphql @@ -34,9 +34,7 @@ query GetRecipe { } mutation AddRecipe { - addRecipe(recipe: { - title: "New Recipe" - }) { + addRecipe(recipe: { title: "New Recipe" }) { id ratings { value @@ -47,11 +45,8 @@ mutation AddRecipe { } } -mutation RateRecipe { - rate(rate: { - recipeId: 3 - value: 4 - }) { +mutation RatingRecipe { + rating(rating: { recipeId: 3, value: 4 }) { id ratings { value diff --git a/examples/typeorm-lazy-relations/helpers.ts b/examples/typeorm-lazy-relations/helpers.ts index 4d5572133..4422a8879 100644 --- a/examples/typeorm-lazy-relations/helpers.ts +++ b/examples/typeorm-lazy-relations/helpers.ts @@ -1,17 +1,14 @@ -import { getRepository } from "typeorm"; - -import { Recipe } from "./entities/recipe"; -import { Rate } from "./entities/rate"; -import { User } from "./entities/user"; +import { dataSource } from "./datasource"; +import { Rating, Recipe, User } from "./entities"; export async function seedDatabase() { - const recipeRepository = getRepository(Recipe); - const ratingsRepository = getRepository(Rate); - const userRepository = getRepository(User); + const recipeRepository = dataSource.getRepository(Recipe); + const ratingRepository = dataSource.getRepository(Rating); + const userRepository = dataSource.getRepository(User); const defaultUser = userRepository.create({ - email: "test@github.com", - nickname: "MichalLytek", + email: "admin@github.com", + nickname: "administrator", password: "s3cr3tp4ssw0rd", }); await userRepository.save(defaultUser); @@ -29,21 +26,18 @@ export async function seedDatabase() { ]); await recipeRepository.save([recipe1, recipe2]); - const ratings = ratingsRepository.create([ + const ratings = ratingRepository.create([ { value: 2, user: defaultUser, recipe: recipe1 }, { value: 4, user: defaultUser, recipe: recipe1 }, { value: 5, user: defaultUser, recipe: recipe1 }, { value: 3, user: defaultUser, recipe: recipe1 }, { value: 4, user: defaultUser, recipe: recipe1 }, - { value: 2, user: defaultUser, recipe: recipe2 }, { value: 4, user: defaultUser, recipe: recipe2 }, ]); - await ratingsRepository.save(ratings); + await ratingRepository.save(ratings); return { defaultUser, }; } - -export type Lazy = Promise | T; diff --git a/examples/typeorm-lazy-relations/index.ts b/examples/typeorm-lazy-relations/index.ts index 60be36469..fc1ddadf9 100644 --- a/examples/typeorm-lazy-relations/index.ts +++ b/examples/typeorm-lazy-relations/index.ts @@ -1,58 +1,41 @@ import "reflect-metadata"; -import { ApolloServer } from "apollo-server"; -import { Container } from "typedi"; -import * as TypeORM from "typeorm"; -import * as TypeGraphQL from "../../src"; - -import { RecipeResolver } from "./resolvers/recipe-resolver"; -import { Recipe } from "./entities/recipe"; -import { Rate } from "./entities/rate"; -import { User } from "./entities/user"; +import "dotenv/config"; +import path from "node:path"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { buildSchema } from "type-graphql"; +import { type Context } from "./context.type"; +import { dataSource } from "./datasource"; import { seedDatabase } from "./helpers"; -import { Context } from "./resolvers/types/context"; - -// register 3rd party IOC container -TypeORM.useContainer(Container); +import { RecipeResolver } from "./resolvers"; async function bootstrap() { - try { - // create TypeORM connection - await TypeORM.createConnection({ - type: "postgres", - database: "type-graphql-lazy", - username: "postgres", // fill this with your username - password: "qwerty", // and password - port: 5434, // and port - host: "localhost", // and host - entities: [Recipe, Rate, User], - synchronize: true, - logger: "advanced-console", - logging: "all", - dropSchema: true, - cache: true, - }); - - // seed database with some data - const { defaultUser } = await seedDatabase(); - - // build TypeGraphQL executable schema - const schema = await TypeGraphQL.buildSchema({ - resolvers: [RecipeResolver], - container: Container, - }); - - // create mocked context - const context: Context = { user: defaultUser }; - - // Create GraphQL server - const server = new ApolloServer({ schema, context }); - - // Start the server - const { url } = await server.listen(4000); - console.log(`Server is running, GraphQL Playground available at ${url}`); - } catch (err) { - console.error(err); - } + // Create TypeORM connection + await dataSource.initialize(); + + // Seed database with some data + const { defaultUser } = await seedDatabase(); + + // Build TypeGraphQL executable schema + const schema = await buildSchema({ + // Array of resolvers + resolvers: [RecipeResolver], + // Create 'schema.graphql' file with schema definition in current directory + emitSchemaFile: path.resolve(__dirname, "schema.graphql"), + }); + + // Create mocked context + const context: Context = { user: defaultUser }; + + // Create GraphQL server + const server = new ApolloServer({ schema }); + + // Start server + const { url } = await startStandaloneServer(server, { + listen: { port: 4000 }, + context: async () => context, + }); + console.log(`GraphQL server ready at ${url}`); } -bootstrap(); +bootstrap().catch(console.error); diff --git a/examples/typeorm-lazy-relations/resolvers/index.ts b/examples/typeorm-lazy-relations/resolvers/index.ts new file mode 100644 index 000000000..1264402cb --- /dev/null +++ b/examples/typeorm-lazy-relations/resolvers/index.ts @@ -0,0 +1 @@ +export * from "./recipe.resolver"; diff --git a/examples/typeorm-lazy-relations/resolvers/recipe-resolver.ts b/examples/typeorm-lazy-relations/resolvers/recipe-resolver.ts deleted file mode 100644 index 567c45af1..000000000 --- a/examples/typeorm-lazy-relations/resolvers/recipe-resolver.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Resolver, Query, Arg, Mutation, Ctx, Int } from "../../../src/"; -import { Repository } from "typeorm"; -import { InjectRepository } from "typeorm-typedi-extensions"; - -import { Recipe } from "../entities/recipe"; -import { Rate } from "../entities/rate"; -import { RecipeInput } from "./types/recipe-input"; -import { RateInput } from "./types/rate-input"; -import { Context } from "./types/context"; - -@Resolver(Recipe) -export class RecipeResolver { - constructor( - @InjectRepository(Recipe) private readonly recipeRepository: Repository, - @InjectRepository(Rate) private readonly ratingsRepository: Repository, - ) {} - - @Query(returns => Recipe, { nullable: true }) - recipe(@Arg("recipeId", type => Int) recipeId: number) { - return this.recipeRepository.findOne(recipeId); - } - - @Query(returns => [Recipe]) - recipes(): Promise { - return this.recipeRepository.find(); - } - - @Mutation(returns => Recipe) - addRecipe(@Arg("recipe") recipeInput: RecipeInput, @Ctx() { user }: Context): Promise { - const recipe = this.recipeRepository.create({ - ...recipeInput, - author: user, - }); - return this.recipeRepository.save(recipe); - } - - @Mutation(returns => Recipe) - async rate(@Ctx() { user }: Context, @Arg("rate") rateInput: RateInput): Promise { - // find the recipe - const recipe = await this.recipeRepository.findOne(rateInput.recipeId, { - relations: ["ratings"], // preload the relation as we will modify it - }); - if (!recipe) { - throw new Error("Invalid recipe ID"); - } - - // add the new recipe rate - (await recipe.ratings).push( - this.ratingsRepository.create({ - recipe, - user, - value: rateInput.value, - }), - ); - - // return updated recipe - return await this.recipeRepository.save(recipe); - } -} diff --git a/examples/typeorm-lazy-relations/resolvers/recipe.resolver.ts b/examples/typeorm-lazy-relations/resolvers/recipe.resolver.ts new file mode 100644 index 000000000..e584cc296 --- /dev/null +++ b/examples/typeorm-lazy-relations/resolvers/recipe.resolver.ts @@ -0,0 +1,62 @@ +import { Arg, Ctx, Int, Mutation, Query, Resolver } from "type-graphql"; +import { type Repository } from "typeorm"; +import { RatingInput, RecipeInput } from "./types"; +import { Context } from "../context.type"; +import { dataSource } from "../datasource"; +import { Rating, Recipe } from "../entities"; + +@Resolver(Recipe) +export class RecipeResolver { + private readonly ratingRepository: Repository; + + private readonly recipeRepository: Repository; + + constructor() { + this.ratingRepository = dataSource.getRepository(Rating); + this.recipeRepository = dataSource.getRepository(Recipe); + } + + @Query(_returns => Recipe, { nullable: true }) + recipe(@Arg("recipeId", _type => Int) recipeId: number) { + return this.recipeRepository.findOneBy({ id: recipeId }); + } + + @Query(_returns => [Recipe]) + recipes(): Promise { + return this.recipeRepository.find(); + } + + @Mutation(_returns => Recipe) + addRecipe(@Arg("recipe") recipeInput: RecipeInput, @Ctx() { user }: Context): Promise { + const recipe = this.recipeRepository.create({ + ...recipeInput, + author: user, + }); + return this.recipeRepository.save(recipe); + } + + @Mutation(_returns => Recipe) + async rating(@Ctx() { user }: Context, @Arg("rating") rateInput: RatingInput): Promise { + // Find the recipe + const recipe = await this.recipeRepository.findOne({ + where: { id: rateInput.recipeId }, + relations: ["ratings"], + }); + if (!recipe) { + throw new Error("Invalid recipe ID"); + } + + // Set the new recipe rating + const newRating = this.ratingRepository.create({ + recipe, + user, + value: rateInput.value, + }); + + // Add the new recipe rating + (await recipe.ratings).push(newRating); + + // Update and return recipe + return this.recipeRepository.save(recipe); + } +} diff --git a/examples/typeorm-lazy-relations/resolvers/types/context.ts b/examples/typeorm-lazy-relations/resolvers/types/context.ts deleted file mode 100644 index 12d1b28c4..000000000 --- a/examples/typeorm-lazy-relations/resolvers/types/context.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { User } from "../../entities/user"; - -export interface Context { - user?: User; -} diff --git a/examples/typeorm-lazy-relations/resolvers/types/index.ts b/examples/typeorm-lazy-relations/resolvers/types/index.ts new file mode 100644 index 000000000..0538b5ca4 --- /dev/null +++ b/examples/typeorm-lazy-relations/resolvers/types/index.ts @@ -0,0 +1,2 @@ +export * from "./rating.input"; +export * from "./recipe.input"; diff --git a/examples/typeorm-lazy-relations/resolvers/types/rate-input.ts b/examples/typeorm-lazy-relations/resolvers/types/rate-input.ts deleted file mode 100644 index e8fb38e12..000000000 --- a/examples/typeorm-lazy-relations/resolvers/types/rate-input.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { InputType, Field, Int, ID } from "../../../../src"; - -@InputType() -export class RateInput { - @Field(type => ID) - recipeId: string; - - @Field(type => Int) - value: number; -} diff --git a/examples/typeorm-lazy-relations/resolvers/types/rating.input.ts b/examples/typeorm-lazy-relations/resolvers/types/rating.input.ts new file mode 100644 index 000000000..cdff2e505 --- /dev/null +++ b/examples/typeorm-lazy-relations/resolvers/types/rating.input.ts @@ -0,0 +1,10 @@ +import { Field, InputType, Int } from "type-graphql"; + +@InputType() +export class RatingInput { + @Field(_type => Int) + recipeId!: number; + + @Field(_type => Int) + value!: number; +} diff --git a/examples/typeorm-lazy-relations/resolvers/types/recipe-input.ts b/examples/typeorm-lazy-relations/resolvers/types/recipe-input.ts deleted file mode 100644 index 44db013d5..000000000 --- a/examples/typeorm-lazy-relations/resolvers/types/recipe-input.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { InputType, Field } from "../../../../src"; - -import { Recipe } from "../../entities/recipe"; - -@InputType() -export class RecipeInput implements Partial { - @Field() - title: string; - - @Field({ nullable: true }) - description: string; -} diff --git a/examples/typeorm-lazy-relations/resolvers/types/recipe.input.ts b/examples/typeorm-lazy-relations/resolvers/types/recipe.input.ts new file mode 100644 index 000000000..93faea28c --- /dev/null +++ b/examples/typeorm-lazy-relations/resolvers/types/recipe.input.ts @@ -0,0 +1,11 @@ +import { Field, InputType } from "type-graphql"; +import { type Recipe } from "../../entities"; + +@InputType() +export class RecipeInput implements Partial { + @Field() + title!: string; + + @Field({ nullable: true }) + description!: string; +} diff --git a/examples/typeorm-lazy-relations/schema.graphql b/examples/typeorm-lazy-relations/schema.graphql new file mode 100644 index 000000000..e79feb7bb --- /dev/null +++ b/examples/typeorm-lazy-relations/schema.graphql @@ -0,0 +1,50 @@ +# ----------------------------------------------- +# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!! +# !!! DO NOT MODIFY THIS FILE BY YOURSELF !!! +# ----------------------------------------------- + +""" +A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar.This scalar is serialized to a string in ISO 8601 format and parsed from a string in ISO 8601 format. +""" +scalar DateTimeISO + +type Mutation { + addRecipe(recipe: RecipeInput!): Recipe! + rating(rating: RatingInput!): Recipe! +} + +type Query { + recipe(recipeId: Int!): Recipe + recipes: [Recipe!]! +} + +type Rating { + date: DateTimeISO! + user: User! + value: Int! +} + +input RatingInput { + recipeId: Int! + value: Int! +} + +type Recipe { + author: User! + description: String + id: ID! + ratings: [Rating!]! + title: String! +} + +input RecipeInput { + description: String + title: String! +} + +type User { + email: String! + id: ID! + nickname: String + recipes: [Recipe!]! +} diff --git a/examples/using-container/examples.graphql b/examples/using-container/examples.graphql new file mode 100644 index 000000000..637acc8de --- /dev/null +++ b/examples/using-container/examples.graphql @@ -0,0 +1,24 @@ +query GetRecipe1 { + recipe(recipeId: "1") { + title + description + ingredients + numberInCollection + } +} + +query GetRecipes { + recipes { + title + description + ingredientsLength + numberInCollection + } +} + +mutation AddRecipe { + addRecipe(recipe: { title: "New recipe", ingredients: ["One", "Two", "Three"] }) { + id + numberInCollection + } +} diff --git a/examples/using-container/index.ts b/examples/using-container/index.ts index eb9efd475..41b6418d8 100644 --- a/examples/using-container/index.ts +++ b/examples/using-container/index.ts @@ -1,28 +1,32 @@ import "reflect-metadata"; -import { ApolloServer } from "apollo-server"; +import path from "node:path"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { buildSchema } from "type-graphql"; import { Container } from "typedi"; -import { buildSchema } from "../../src"; +import { sampleRecipes } from "./recipe.data"; +import { RecipeResolver } from "./recipe.resolver"; -import { RecipeResolver } from "./recipe-resolver"; -import { sampleRecipes } from "./sample-recipes"; - -// put sample recipes in container +// Add sample recipes in container Container.set({ id: "SAMPLE_RECIPES", factory: () => sampleRecipes.slice() }); async function bootstrap() { - // build TypeGraphQL executable schema + // Build TypeGraphQL executable schema const schema = await buildSchema({ + // Array of resolvers resolvers: [RecipeResolver], - // register 3rd party IOC container + // Registry 3rd party IOC container container: Container, + // Create 'schema.graphql' file with schema definition in current directory + emitSchemaFile: path.resolve(__dirname, "schema.graphql"), }); // Create GraphQL server const server = new ApolloServer({ schema }); - // Start the server - const { url } = await server.listen(4000); - console.log(`Server is running, GraphQL Playground available at ${url}`); + // Start server + const { url } = await startStandaloneServer(server, { listen: { port: 4000 } }); + console.log(`GraphQL server ready at ${url}`); } -bootstrap(); +bootstrap().catch(console.error); diff --git a/examples/using-container/recipe-input.ts b/examples/using-container/recipe-input.ts deleted file mode 100644 index a49ed43bf..000000000 --- a/examples/using-container/recipe-input.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Recipe } from "./recipe-type"; -import { InputType, Field } from "../../src"; - -@InputType() -export class RecipeInput implements Partial { - @Field({ nullable: true }) - description: string; - - @Field(type => [String]) - ingredients: string[]; - - @Field() - title: string; -} diff --git a/examples/using-container/recipe-type.ts b/examples/using-container/recipe-type.ts deleted file mode 100644 index 6ea7531be..000000000 --- a/examples/using-container/recipe-type.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Field, ID, ObjectType, Int } from "../../src"; - -@ObjectType() -export class Recipe { - @Field(type => ID) - id: string; - - @Field() - title: string; - - @Field({ nullable: true }) - description?: string; - - @Field(type => [String]) - ingredients: string[]; - - @Field(type => Int) - protected numberInCollection: number; - - @Field(type => Int) - protected get ingredientsLength(): number { - return this.ingredients.length; - } -} diff --git a/examples/using-container/recipe.data.ts b/examples/using-container/recipe.data.ts new file mode 100644 index 000000000..288d850e5 --- /dev/null +++ b/examples/using-container/recipe.data.ts @@ -0,0 +1,25 @@ +import { Recipe } from "./recipe.type"; + +function createRecipe(recipeData: Partial): Recipe { + return Object.assign(new Recipe(), recipeData); +} + +export const sampleRecipes = [ + createRecipe({ + id: "1", + title: "Recipe 1", + description: "Desc 1", + ingredients: ["one", "two", "three"], + }), + createRecipe({ + id: "2", + title: "Recipe 2", + description: "Desc 2", + ingredients: ["four", "five", "six"], + }), + createRecipe({ + id: "3", + title: "Recipe 3", + ingredients: ["seven", "eight", "nine"], + }), +]; diff --git a/examples/using-container/recipe.input.ts b/examples/using-container/recipe.input.ts new file mode 100644 index 000000000..97ec17bce --- /dev/null +++ b/examples/using-container/recipe.input.ts @@ -0,0 +1,14 @@ +import { Field, InputType } from "type-graphql"; +import { type Recipe } from "./recipe.type"; + +@InputType() +export class RecipeInput implements Partial { + @Field() + title!: string; + + @Field({ nullable: true }) + description?: string; + + @Field(_type => [String]) + ingredients!: string[]; +} diff --git a/examples/using-container/recipe-resolver.ts b/examples/using-container/recipe.resolver.ts similarity index 58% rename from examples/using-container/recipe-resolver.ts rename to examples/using-container/recipe.resolver.ts index 01fc96c5d..2b435574c 100644 --- a/examples/using-container/recipe-resolver.ts +++ b/examples/using-container/recipe.resolver.ts @@ -1,29 +1,29 @@ -import { Service } from "typedi"; -import { Resolver, Query, FieldResolver, Arg, Root, Mutation } from "../../src"; - -import { Recipe } from "./recipe-type"; -import { RecipeService } from "./recipe-service"; -import { RecipeInput } from "./recipe-input"; +import { Arg, FieldResolver, Mutation, Query, Resolver, Root } from "type-graphql"; +import { Inject, Service } from "typedi"; +import { RecipeInput } from "./recipe.input"; +import { RecipeService } from "./recipe.service"; +import { Recipe } from "./recipe.type"; @Service() -@Resolver(of => Recipe) +@Resolver(_of => Recipe) export class RecipeResolver { constructor( - // constructor injection of service + // Inject service + @Inject() private readonly recipeService: RecipeService, ) {} - @Query(returns => Recipe, { nullable: true }) + @Query(_returns => Recipe, { nullable: true }) async recipe(@Arg("recipeId") recipeId: string) { return this.recipeService.getOne(recipeId); } - @Query(returns => [Recipe]) + @Query(_returns => [Recipe]) async recipes(): Promise { return this.recipeService.getAll(); } - @Mutation(returns => Recipe) + @Mutation(_returns => Recipe) async addRecipe(@Arg("recipe") recipe: RecipeInput): Promise { return this.recipeService.add(recipe); } diff --git a/examples/using-container/recipe.service.ts b/examples/using-container/recipe.service.ts new file mode 100644 index 000000000..763003355 --- /dev/null +++ b/examples/using-container/recipe.service.ts @@ -0,0 +1,47 @@ +import { Inject, Service } from "typedi"; +import { type RecipeInput } from "./recipe.input"; +import { Recipe } from "./recipe.type"; + +@Service() +export class RecipeService { + private autoIncrementValue: number; + + constructor( + @Inject("SAMPLE_RECIPES") + private readonly items: Recipe[], + ) { + this.autoIncrementValue = this.items.length; + } + + async getAll() { + return this.items; + } + + async getOne(id: string) { + return this.items.find(it => it.id === id); + } + + async add(data: RecipeInput) { + const recipe = this.createRecipe(data); + this.items.push(recipe); + + return recipe; + } + + async findIndex(recipe: Recipe) { + return this.items.findIndex(it => it.id === recipe.id); + } + + private createRecipe(recipeData: Partial): Recipe { + const recipe = Object.assign(new Recipe(), recipeData); + recipe.id = this.getId(); + + return recipe; + } + + private getId(): string { + this.autoIncrementValue += 1; + + return this.autoIncrementValue.toString(); + } +} diff --git a/examples/using-container/recipe.type.ts b/examples/using-container/recipe.type.ts new file mode 100644 index 000000000..d2d0078ad --- /dev/null +++ b/examples/using-container/recipe.type.ts @@ -0,0 +1,24 @@ +import { Field, ID, Int, ObjectType } from "type-graphql"; + +@ObjectType() +export class Recipe { + @Field(_type => ID) + id!: string; + + @Field() + title!: string; + + @Field({ nullable: true }) + description?: string; + + @Field(_type => [String]) + ingredients!: string[]; + + @Field(_type => Int) + protected numberInCollection!: number; + + @Field(_type => Int) + protected get ingredientsLength(): number { + return this.ingredients.length; + } +} diff --git a/examples/using-container/schema.graphql b/examples/using-container/schema.graphql new file mode 100644 index 000000000..efcbbf066 --- /dev/null +++ b/examples/using-container/schema.graphql @@ -0,0 +1,28 @@ +# ----------------------------------------------- +# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!! +# !!! DO NOT MODIFY THIS FILE BY YOURSELF !!! +# ----------------------------------------------- + +type Mutation { + addRecipe(recipe: RecipeInput!): Recipe! +} + +type Query { + recipe(recipeId: String!): Recipe + recipes: [Recipe!]! +} + +type Recipe { + description: String + id: ID! + ingredients: [String!]! + ingredientsLength: Int! + numberInCollection: Int! + title: String! +} + +input RecipeInput { + description: String + ingredients: [String!]! + title: String! +} diff --git a/examples/using-scoped-container/types.ts b/examples/using-scoped-container/context.type.ts similarity index 62% rename from examples/using-scoped-container/types.ts rename to examples/using-scoped-container/context.type.ts index d35bae5c3..5ccbd7c3a 100644 --- a/examples/using-scoped-container/types.ts +++ b/examples/using-scoped-container/context.type.ts @@ -1,4 +1,4 @@ -import { ContainerInstance } from "typedi"; +import { type ContainerInstance } from "typedi"; export interface Context { requestId: number; diff --git a/examples/using-scoped-container/examples.gql b/examples/using-scoped-container/examples.graphql similarity index 69% rename from examples/using-scoped-container/examples.gql rename to examples/using-scoped-container/examples.graphql index 22152b814..4b81d4d6c 100644 --- a/examples/using-scoped-container/examples.gql +++ b/examples/using-scoped-container/examples.graphql @@ -20,14 +20,7 @@ query GetRecipes { } mutation AddRecipe { - addRecipe(recipe: { - title: "New recipe", - ingredients: [ - "One", - "Two", - "Three", - ], - }) { + addRecipe(recipe: { title: "New recipe", ingredients: ["One", "Two", "Three"] }) { id title } diff --git a/examples/using-scoped-container/index.ts b/examples/using-scoped-container/index.ts index c7cfd56fd..7da4ec2e5 100644 --- a/examples/using-scoped-container/index.ts +++ b/examples/using-scoped-container/index.ts @@ -1,57 +1,63 @@ import "reflect-metadata"; -import { ApolloServer } from "apollo-server"; -import Container, { ContainerInstance } from "typedi"; -import { GraphQLRequestContext, ApolloServerPlugin } from "apollo-server-plugin-base"; -import { buildSchema, ResolverData } from "../../src"; - +import path from "node:path"; +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { type ResolverData, buildSchema } from "type-graphql"; +import { Container, type ContainerInstance } from "typedi"; +import { type Context } from "./context.type"; +import { setSamplesInContainer } from "./recipe/recipe.data"; import { RecipeResolver } from "./recipe/recipe.resolver"; -import { Context } from "./types"; -import { setSamplesInContainer } from "./recipe/recipe.samples"; async function bootstrap() { setSamplesInContainer(); - // build TypeGraphQL executable schema + // Build TypeGraphQL executable schema const schema = await buildSchema({ + // Array of resolvers resolvers: [RecipeResolver], - // register our custom, scoped IOC container by passing a extracting from resolver data function + // Registry custom, scoped IOC container from resolver data function container: ({ context }: ResolverData) => context.container, + // Create 'schema.graphql' file with schema definition in current directory + emitSchemaFile: path.resolve(__dirname, "schema.graphql"), }); - // create GraphQL server - const server = new ApolloServer({ + // Create GraphQL server + const server = new ApolloServer({ schema, - // we need to provide unique context with `requestId` for each request - context: (): Context => { - const requestId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // uuid-like - const container = Container.of(requestId.toString()); // get scoped container - const context = { requestId, container }; // create our context - container.set("context", context); // place context or other data in container - return context; - }, - // create a plugin that will allow for disposing the scoped container created for every request + // Create a plugin to allow for disposing the scoped container created for every request plugins: [ { - requestDidStart: () => ({ - willSendResponse(requestContext: GraphQLRequestContext) { - // remember to dispose the scoped container to prevent memory leaks - Container.reset(requestContext.context.requestId.toString()); + requestDidStart: async () => ({ + async willSendResponse(requestContext) { + // Dispose the scoped container to prevent memory leaks + Container.reset(requestContext.contextValue.requestId.toString()); - // for developers curiosity purpose, here is the logging of current scoped container instances - // we can make multiple parallel requests to see in console how this works + // For developers curiosity purpose, here is the logging of current scoped container instances + // Make multiple parallel requests to see in console how this works const instancesIds = ((Container as any).instances as ContainerInstance[]).map( instance => instance.id, ); - console.log("instances left in memory:", instancesIds); + console.log("Instances left in memory: ", instancesIds); }, }), }, - ] as ApolloServerPlugin[], // TODO: remove when fixed: https://github.com/apollographql/apollo-server/pull/3525 + ], }); - // start the server - const { url } = await server.listen(4000); - console.log(`Server is running, GraphQL Playground available at ${url}`); + // Start server + const { url } = await startStandaloneServer(server, { + listen: { port: 4000 }, + // Provide unique context with 'requestId' for each request + context: async () => { + const requestId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // uuid-like + const container = Container.of(requestId.toString()); // Get scoped container + const context = { requestId, container }; // Create context + container.set("context", context); // Set context or other data in container + + return context; + }, + }); + console.log(`GraphQL server ready at ${url}`); } -bootstrap(); +bootstrap().catch(console.error); diff --git a/examples/using-scoped-container/logger.ts b/examples/using-scoped-container/logger.ts index 79a797eee..fddaf01a3 100644 --- a/examples/using-scoped-container/logger.ts +++ b/examples/using-scoped-container/logger.ts @@ -1,8 +1,7 @@ -import { Service, Inject } from "typedi"; +import { Inject, Service } from "typedi"; +import { Context } from "./context.type"; -import { Context } from "./types"; - -// this service will be recreated for each request (scoped) +// Service is recreated for each request (scoped) @Service() export class Logger { constructor(@Inject("context") private readonly context: Context) { diff --git a/examples/using-scoped-container/recipe/recipe.samples.ts b/examples/using-scoped-container/recipe/recipe.data.ts similarity index 88% rename from examples/using-scoped-container/recipe/recipe.samples.ts rename to examples/using-scoped-container/recipe/recipe.data.ts index 06f1de37c..eed7ac47e 100644 --- a/examples/using-scoped-container/recipe/recipe.samples.ts +++ b/examples/using-scoped-container/recipe/recipe.data.ts @@ -1,7 +1,10 @@ import Container from "typedi"; - import { Recipe } from "./recipe.type"; +function createRecipe(recipeData: Partial): Recipe { + return Object.assign(new Recipe(), recipeData); +} + export const sampleRecipes = [ createRecipe({ id: "1", @@ -22,15 +25,11 @@ export const sampleRecipes = [ }), ]; -function createRecipe(recipeData: Partial): Recipe { - return Object.assign(new Recipe(), recipeData); -} - export function setSamplesInContainer() { - // add sample recipes to container + // Add sample recipes to container Container.set({ id: "SAMPLE_RECIPES", - transient: true, // create a fresh copy for each `get` of samples + transient: true, // Create a fresh copy for each 'get' of samples factory: () => { console.log("sampleRecipes copy created!"); return sampleRecipes.slice(); diff --git a/examples/using-scoped-container/recipe/recipe.input.ts b/examples/using-scoped-container/recipe/recipe.input.ts index bb5365e8f..5ddac13a1 100644 --- a/examples/using-scoped-container/recipe/recipe.input.ts +++ b/examples/using-scoped-container/recipe/recipe.input.ts @@ -1,15 +1,14 @@ -import { InputType, Field } from "../../../src"; - -import { Recipe } from "./recipe.type"; +import { Field, InputType } from "type-graphql"; +import { type Recipe } from "./recipe.type"; @InputType() export class RecipeInput implements Partial { - @Field({ nullable: true }) - description: string; + @Field() + title!: string; - @Field(type => [String]) - ingredients: string[]; + @Field({ nullable: true }) + description!: string; - @Field() - title: string; + @Field(_type => [String]) + ingredients!: string[]; } diff --git a/examples/using-scoped-container/recipe/recipe.resolver.ts b/examples/using-scoped-container/recipe/recipe.resolver.ts index c8134d2d0..e5b49a837 100644 --- a/examples/using-scoped-container/recipe/recipe.resolver.ts +++ b/examples/using-scoped-container/recipe/recipe.resolver.ts @@ -1,39 +1,47 @@ -import { Service } from "typedi"; -import { Resolver, Query, Arg, Ctx, Mutation } from "../../../src"; - -import { Recipe } from "./recipe.type"; +import { Arg, Ctx, Mutation, Query, Resolver } from "type-graphql"; +import { Inject, Service } from "typedi"; +import { RecipeInput } from "./recipe.input"; import { RecipeService } from "./recipe.service"; +import { Recipe } from "./recipe.type"; +import { Context } from "../context.type"; import { Logger } from "../logger"; -import { Context } from "../types"; -import { RecipeInput } from "./recipe.input"; -const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); +const delay = (time: number) => + new Promise(resolve => { + setTimeout(resolve, time); + }); -// this resolver will be recreated for each request (scoped) +// Resolver is recreated for each request (scoped) @Service() -@Resolver(of => Recipe) +@Resolver(_of => Recipe) export class RecipeResolver { - constructor(private readonly recipeService: RecipeService, private readonly logger: Logger) { + constructor( + @Inject() + private readonly recipeService: RecipeService, + @Inject() + private readonly logger: Logger, + ) { console.log("RecipeResolver created!"); } - @Query(returns => Recipe, { nullable: true }) + @Query(_returns => Recipe, { nullable: true }) async recipe(@Arg("recipeId") recipeId: string, @Ctx() { requestId }: Context) { const recipe = await this.recipeService.getOne(recipeId); if (!recipe) { - console.log("request ID:", requestId); // the same requestId that logger has + console.log("request ID:", requestId); // Same requestId of logger this.logger.log(`Recipe ${recipeId} not found!`); } + return recipe; } - @Query(returns => [Recipe]) + @Query(_returns => [Recipe]) async recipes(): Promise { - await delay(5000); // simulate delay to allow for manual concurrent requests + await delay(5000); // Simulate delay to allow for manual concurrent requests return this.recipeService.getAll(); } - @Mutation(returns => Recipe) + @Mutation(_returns => Recipe) async addRecipe(@Arg("recipe") recipe: RecipeInput): Promise { return this.recipeService.add(recipe); } diff --git a/examples/using-scoped-container/recipe/recipe.service.ts b/examples/using-scoped-container/recipe/recipe.service.ts index ff8819d21..3154ef4cc 100644 --- a/examples/using-scoped-container/recipe/recipe.service.ts +++ b/examples/using-scoped-container/recipe/recipe.service.ts @@ -1,9 +1,8 @@ -import { Service, Inject } from "typedi"; - +import { Inject, Service } from "typedi"; +import { type RecipeInput } from "./recipe.input"; import { Recipe } from "./recipe.type"; -import { RecipeInput } from "./recipe.input"; -// this service will be global - shared by every request +// Service is global, shared by every request @Service({ global: true }) export class RecipeService { private autoIncrementValue: number; @@ -24,6 +23,7 @@ export class RecipeService { async add(data: RecipeInput) { const recipe = this.createRecipe(data); this.items.push(recipe); + return recipe; } @@ -32,10 +32,13 @@ export class RecipeService { ...recipeData, id: this.getId(), }); + return recipe; } private getId(): string { - return (++this.autoIncrementValue).toString(); + this.autoIncrementValue += 1; + + return this.autoIncrementValue.toString(); } } diff --git a/examples/using-scoped-container/recipe/recipe.type.ts b/examples/using-scoped-container/recipe/recipe.type.ts index c86e96b7a..c10e24fd8 100644 --- a/examples/using-scoped-container/recipe/recipe.type.ts +++ b/examples/using-scoped-container/recipe/recipe.type.ts @@ -1,16 +1,16 @@ -import { Field, ID, ObjectType } from "../../../src"; +import { Field, ID, ObjectType } from "type-graphql"; @ObjectType() export class Recipe { - @Field(type => ID) - id: string; + @Field(_type => ID) + id!: string; @Field() - title: string; + title!: string; @Field({ nullable: true }) description?: string; - @Field(type => [String]) - ingredients: string[]; + @Field(_type => [String]) + ingredients!: string[]; } diff --git a/examples/using-scoped-container/schema.graphql b/examples/using-scoped-container/schema.graphql new file mode 100644 index 000000000..f43ff2d23 --- /dev/null +++ b/examples/using-scoped-container/schema.graphql @@ -0,0 +1,26 @@ +# ----------------------------------------------- +# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!! +# !!! DO NOT MODIFY THIS FILE BY YOURSELF !!! +# ----------------------------------------------- + +type Mutation { + addRecipe(recipe: RecipeInput!): Recipe! +} + +type Query { + recipe(recipeId: String!): Recipe + recipes: [Recipe!]! +} + +type Recipe { + description: String + id: ID! + ingredients: [String!]! + title: String! +} + +input RecipeInput { + description: String + ingredients: [String!]! + title: String! +} diff --git a/gulpfile.ts b/gulpfile.ts deleted file mode 100644 index 0f8711d4b..000000000 --- a/gulpfile.ts +++ /dev/null @@ -1,210 +0,0 @@ -import { Gulpclass, MergedTask, SequenceTask, Task } from "gulpclass"; - -import gulp from "gulp"; -import del from "del"; -import shell from "gulp-shell"; -import replace from "gulp-replace"; -import ts from "gulp-typescript"; -// import tslint from "gulp-tslint"; -// const stylish = require("tslint-stylish"); -// const sourcemaps = require("gulp-sourcemaps"); -// const mocha = require("gulp-mocha"); -// const chai = require("chai"); -// const istanbul = require("gulp-istanbul"); -// const remapIstanbul = require("remap-istanbul/lib/gulpRemapIstanbul"); - -@Gulpclass() -export class Gulpfile { - // ------------------------------------------------------------------------- - // General tasks - // ------------------------------------------------------------------------- - - /** - * Cleans build folder. - */ - @Task() - clean(cb: del.Options) { - return del(["build/**"], cb); - } - - /** - * Runs typescript files compilation. - */ - @Task() - compile() { - return gulp.src("*.ts", { read: false }).pipe(shell(["tsc"])); - } - - // ------------------------------------------------------------------------- - // Packaging and Publishing tasks - // ------------------------------------------------------------------------- - - /** - * Publishes a package to npm from ./build/package directory. - */ - @Task() - npmPublish() { - return gulp.src("*.js", { read: false }).pipe(shell(["cd ./build/package && npm publish"])); - } - - /** - * Complies all sources to the package directory. - */ - @MergedTask() - packageCompile() { - const tsProject = ts.createProject("tsconfig.package.json"); - const tsResult = tsProject - .src() - // .pipe(sourcemaps.init()) - .pipe(tsProject()); - - return [ - tsResult.dts.pipe(gulp.dest("./build/package/dist")), - tsResult.js - // .pipe(sourcemaps.write(".", { sourceRoot: "", includeContent: true })) - .pipe(gulp.dest("./build/package/dist")), - ]; - } - - /** - * Copy over the browser-shim files instead of compiling them. - * The .js file supports ES5 and newer browsers. - * The .ts file supports Angular and other TypeScript projects. - */ - @MergedTask() - packageBrowserShim() { - return [ - gulp.src("./src/browser-shim.ts").pipe(gulp.dest("./build/package/dist")), - del(["./build/package/dist/browser-shim.d.ts"]), - ]; - } - - /** - * Moves all compiled files to the final package directory. - */ - // @Task() - // packageMoveCompiledFiles() { - // return gulp.src("./build/package/src/**/*").pipe(gulp.dest("./build/package/dist")); - // } - - /** - * Removes unnecessary files from final package directory. - */ - // @Task() - // packageClearCompileDirectory(cb: del.Options) { - // return del( - // ["./build/package/src/**", "./build/package/tests/**", "./build/package/examples/**"], - // cb, - // ); - // } - - /** - * Change the "private" state of the packaged package.json file to public. - */ - @Task() - packagePreparePackageFile() { - return gulp - .src("./package.json") - .pipe(replace('"private": true', '"private": false')) - .pipe(gulp.dest("./build/package")); - } - - /** - * This task will replace all typescript code blocks in the README - * (since npm does not support typescript syntax highlighting) - * and copy this README file into the package folder. - */ - @Task() - packageReadmeFile() { - return gulp - .src("./README.md") - .pipe(replace(/```ts([\s\S]*?)```/g, "```js$1```")) - .pipe(gulp.dest("./build/package")); - } - - /** - * Creates a package that can be published to npm. - */ - @SequenceTask() - package() { - return [ - "clean", - "packageCompile", - "packageBrowserShim", - // "packageMoveCompiledFiles", - // "packageClearCompileDirectory", - ["packagePreparePackageFile", "packageReadmeFile"], - ]; - } - - /** - * Creates a package and publishes it to npm. - */ - @SequenceTask() - publish() { - return ["package", "npmPublish"]; - } - - // ------------------------------------------------------------------------- - // Run tests tasks - // ------------------------------------------------------------------------- - - /** - * Runs ts linting to validate source code. - */ - // @Task() - // tslint() { - // return gulp - // .src(["./src/**/*.ts", "./test/**/*.ts", "./sample/**/*.ts"]) - // .pipe(tslint()) - // .pipe( - // tslint.report(stylish, { - // emitError: true, - // sort: true, - // bell: true, - // }), - // ); - // } - - /** - * Runs before test coverage, required step to perform a test coverage. - */ - // @Task() - // coveragePre() { - // return gulp - // .src(["./build/compiled/src/**/*.js"]) - // .pipe(istanbul()) - // .pipe(istanbul.hookRequire()); - // } - - /** - * Runs post coverage operations. - */ - // @Task("coveragePost", ["coveragePre"]) - // coveragePost() { - // chai.should(); - // // chai.use(require("sinon-chai")); - // // chai.use(require("chai-as-promised")); - - // return gulp - // .src(["./build/compiled/test/functional/**/*.js", "./build/compiled/test/issues/**/*.js"]) - // .pipe(mocha()) - // .pipe(istanbul.writeReports()); - // } - - // @Task() - // coverageRemap() { - // return gulp - // .src("./coverage/coverage-final.json") - // .pipe(remapIstanbul()) - // .pipe(gulp.dest("./coverage")); - // } - - /** - * Compiles the code and runs tests. - */ - // @SequenceTask() - // tests() { - // return ["clean", "compile", "coveragePost", "coverageRemap", "tslint"]; - // } -} diff --git a/images/admin-remix.png b/images/admin-remix.png new file mode 100644 index 000000000..8d4d799bf Binary files /dev/null and b/images/admin-remix.png differ diff --git a/img/alka.png b/images/alka.png similarity index 100% rename from img/alka.png rename to images/alka.png diff --git a/img/blue_receipt.gif b/images/blue_receipt.gif similarity index 100% rename from img/blue_receipt.gif rename to images/blue_receipt.gif diff --git a/images/casinodeps.svg b/images/casinodeps.svg new file mode 100644 index 000000000..92083ec06 --- /dev/null +++ b/images/casinodeps.svg @@ -0,0 +1 @@ +Asset 3 \ No newline at end of file diff --git a/img/chums.svg b/images/chums.svg similarity index 100% rename from img/chums.svg rename to images/chums.svg diff --git a/img/ecad.png b/images/ecad.png similarity index 100% rename from img/ecad.png rename to images/ecad.png diff --git a/images/ecad_new.png b/images/ecad_new.png new file mode 100644 index 000000000..0efd15ad2 Binary files /dev/null and b/images/ecad_new.png differ diff --git a/images/flatirons.png b/images/flatirons.png new file mode 100644 index 000000000..4ef35ebc9 Binary files /dev/null and b/images/flatirons.png differ diff --git a/images/github-sponsors.svg b/images/github-sponsors.svg new file mode 100644 index 000000000..d44844487 --- /dev/null +++ b/images/github-sponsors.svg @@ -0,0 +1,130 @@ + + + + +Bronze Sponsors πŸ₯‰ + Jan-Henrik + +Members πŸ’ͺ + + +Backers β˜• + + + + + + + + + + +Past Sponsors ⏳ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/img/gorrion.png b/images/gorrion.png similarity index 100% rename from img/gorrion.png rename to images/gorrion.png diff --git a/images/instinctools.svg b/images/instinctools.svg new file mode 100644 index 000000000..05db3a239 --- /dev/null +++ b/images/instinctools.svg @@ -0,0 +1,14 @@ + + + + background + + + + Layer 1 + + + + + + \ No newline at end of file diff --git a/images/intexsoft.jpg b/images/intexsoft.jpg new file mode 100644 index 000000000..21128a138 Binary files /dev/null and b/images/intexsoft.jpg differ diff --git a/img/lifex.png b/images/lifex.png similarity index 100% rename from img/lifex.png rename to images/lifex.png diff --git a/img/live-graphics-system.png b/images/live-graphics-system.png similarity index 100% rename from img/live-graphics-system.png rename to images/live-graphics-system.png diff --git a/img/logo.png b/images/logo.png similarity index 100% rename from img/logo.png rename to images/logo.png diff --git a/images/lovd.png b/images/lovd.png new file mode 100644 index 000000000..38315c424 Binary files /dev/null and b/images/lovd.png differ diff --git a/img/mr-yum.png b/images/mr-yum.png similarity index 100% rename from img/mr-yum.png rename to images/mr-yum.png diff --git a/images/non-gamstop-casinos.svg b/images/non-gamstop-casinos.svg new file mode 100644 index 000000000..35cdfb8d7 --- /dev/null +++ b/images/non-gamstop-casinos.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/non-stop-casino.png b/images/non-stop-casino.png new file mode 100644 index 000000000..84aace8d6 Binary files /dev/null and b/images/non-stop-casino.png differ diff --git a/images/nongamstopbets.png b/images/nongamstopbets.png new file mode 100644 index 000000000..08e3b6159 Binary files /dev/null and b/images/nongamstopbets.png differ diff --git a/images/pwmlogo.png b/images/pwmlogo.png new file mode 100644 index 000000000..356c50346 Binary files /dev/null and b/images/pwmlogo.png differ diff --git a/images/qulix.png b/images/qulix.png new file mode 100644 index 000000000..e13133595 Binary files /dev/null and b/images/qulix.png differ diff --git a/images/rubydroid.svg b/images/rubydroid.svg new file mode 100644 index 000000000..a23560844 --- /dev/null +++ b/images/rubydroid.svg @@ -0,0 +1,24 @@ + + + + F8DCB9AC-40FA-4ADB-8604-6311CFC9450D-416-0000F5A4C92BF4F5 + Created with sketchtool. + + + + + + + + + + + \ No newline at end of file diff --git a/images/slon.png b/images/slon.png new file mode 100644 index 000000000..2a8bb349f Binary files /dev/null and b/images/slon.png differ diff --git a/img/swiss-mentor.png b/images/swiss-mentor.png similarity index 100% rename from img/swiss-mentor.png rename to images/swiss-mentor.png diff --git a/images/vps-server.png b/images/vps-server.png new file mode 100644 index 000000000..60ca38537 Binary files /dev/null and b/images/vps-server.png differ diff --git a/jest.config.js b/jest.config.js deleted file mode 100644 index e3f727394..000000000 --- a/jest.config.js +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = { - verbose: false, - transform: { - "^.+\\.tsx?$": "ts-jest", - }, - testMatch: ["**/functional/**/*.ts", "**/units/**/*.ts"], - moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], - rootDir: "./", - roots: ["/tests", "/src"], - collectCoverage: false, - collectCoverageFrom: [ - "/src/**/*.ts", - "!/src/**/*.d.ts", - "!/src/browser-shim.ts", - ], - coverageDirectory: "/coverage", - testEnvironment: "node", -}; diff --git a/jest.config.ts b/jest.config.ts new file mode 100644 index 000000000..0de02dafb --- /dev/null +++ b/jest.config.ts @@ -0,0 +1,25 @@ +import { pathsToModuleNameMapper, JestConfigWithTsJest } from "ts-jest"; +import tsconfig from "./tsconfig.json"; + +export default { + preset: "ts-jest", + verbose: false, + rootDir: "./", + roots: ["/src", "/tests"], + testEnvironment: "node", + collectCoverage: false, + collectCoverageFrom: [ + "/src/**/*.ts", + "!/src/**/*.d.ts", + "!/src/shim.ts", + ], + moduleNameMapper: pathsToModuleNameMapper(tsconfig.compilerOptions.paths, { + prefix: "", + }), + transform: { + "^.+\\.tsx?$": ["ts-jest", { tsconfig: "./tests/tsconfig.json" }], + }, + testMatch: ["**/functional/**/*.ts"], + moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], + coverageDirectory: "/coverage", +} satisfies JestConfigWithTsJest; diff --git a/package-lock.json b/package-lock.json index e1998eb03..cb840f1b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,129 +1,244 @@ { "name": "type-graphql", - "version": "0.0.0-unreleased", - "lockfileVersion": 2, + "version": "2.0.0-rc.1", + "lockfileVersion": 3, "requires": true, "packages": { "": { - "version": "0.0.0-unreleased", - "hasInstallScript": true, + "name": "type-graphql", + "version": "2.0.0-rc.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/TypeGraphQL" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/typegraphql" + } + ], "license": "MIT", "dependencies": { - "@types/glob": "^7.1.3", + "@graphql-yoga/subscription": "^5.0.0", "@types/node": "*", - "@types/semver": "^7.3.4", - "glob": "^7.1.6", - "graphql-query-complexity": "^0.7.2", - "graphql-subscriptions": "^1.2.0", - "semver": "^7.3.4", - "tslib": "^2.1.0" + "@types/semver": "^7.5.6", + "graphql-query-complexity": "^0.12.0", + "semver": "^7.5.4", + "tslib": "^2.6.2" }, "devDependencies": { - "@apollo/federation": "^0.21.2", - "@apollo/gateway": "^0.23.2", - "@graphql-modules/core": "^0.7.13", - "@graphql-modules/di": "^0.7.17", - "@mikro-orm/core": "^4.4.4", - "@mikro-orm/postgresql": "^4.4.4", - "@typegoose/typegoose": "^7.4.8", - "@types/gulp": "^4.0.8", - "@types/gulp-replace": "0.0.31", - "@types/ioredis": "^4.22.0", - "@types/jest": "^26.0.20", - "@types/mongoose": "^5.10.3", - "@types/node": "^14.14.31", - "@types/rimraf": "^3.0.0", - "apollo-cache-control": "^0.11.6", - "apollo-server": "^2.21.0", - "apollo-server-plugin-response-cache": "^0.6.0", - "class-validator": "^0.13.1", - "del": "^6.0.0", - "graphql": "^15.5.0", - "graphql-redis-subscriptions": "^2.3.1", - "graphql-tag": "^2.11.0", - "gulp-replace": "^1.0.0", - "gulp-shell": "^0.8.0", - "gulp-typescript": "^5.0.1", - "gulpclass": "^0.2.0", - "husky": "^4.3.8", - "ioredis": "^4.23.0", - "jest": "^26.6.3", - "joiful": "^3.0.0", - "lint-staged": "^10.5.4", - "mongoose": "5.10.18", - "pg": "^8.5.1", - "prettier": "^2.2.1", + "@apollo/cache-control-types": "^1.0.3", + "@apollo/gateway": "^2.7.1", + "@apollo/server": "^4.10.0", + "@apollo/server-plugin-response-cache": "^4.1.3", + "@apollo/subgraph": "^2.7.1", + "@cspell/dict-node": "^4.0.3", + "@cspell/dict-npm": "^5.0.14", + "@cspell/dict-shell": "^1.0.6", + "@cspell/dict-typescript": "^3.1.2", + "@cspell/eslint-plugin": "^8.3.2", + "@graphql-tools/schema": "^10.0.2", + "@graphql-tools/utils": "^10.1.2", + "@graphql-yoga/redis-event-target": "^3.0.0", + "@mikro-orm/core": "^6.0.2", + "@mikro-orm/postgresql": "^6.2.1", + "@typegoose/typegoose": "^12.2.0", + "@types/jest": "^29.5.11", + "@types/lodash.merge": "^4.6.9", + "@types/node": "^20.11.24", + "@types/shelljs": "^0.8.15", + "@types/yargs": "^17.0.32", + "@typescript-eslint/eslint-plugin": "^6.18.1", + "@typescript-eslint/parser": "^6.18.1", + "class-validator": "^0.14.0", + "cspell": "^8.7.0", + "dotenv": "^16.4.5", + "eslint": "^8.56.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-airbnb-typescript": "^17.1.0", + "eslint-config-prettier": "^9.1.0", + "eslint-import-resolver-typescript": "^3.6.1", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-jest": "^27.6.2", + "eslint-plugin-tsdoc": "^0.2.17", + "expect": "^29.7.0", + "glob": "^10.3.10", + "graphql": "^16.8.1", + "graphql-scalars": "^1.22.4", + "graphql-tag": "^2.12.6", + "graphql-yoga": "^5.1.1", + "husky": "^8.0.3", + "ioredis": "^5.3.2", + "jest": "^29.7.0", + "joiful": "^3.0.2", + "lint-staged": "^15.2.0", + "lodash.merge": "^4.6.2", + "markdownlint": "^0.33.0", + "markdownlint-cli": "^0.38.0", + "mongoose": "^8.0.4", + "npm-run-all": "^4.1.5", + "pg": "^8.11.3", + "prettier": "^3.2.5", + "prettier-plugin-sh": "^0.14.0", "reflect-metadata": "^0.1.13", - "rimraf": "^3.0.2", - "ts-jest": "^26.5.2", - "ts-node": "^9.1.1", - "tslint": "^6.1.3", - "tslint-config-prettier": "^1.18.0", - "tslint-eslint-rules": "^5.4.0", + "shellcheck": "^2.2.0", + "shelljs": "^0.8.5", + "shx": "^0.3.4", + "sponsorkit": "^0.9.1", + "ts-jest": "^29.1.1", + "ts-node": "^10.9.2", + "ts-patch": "^3.1.1", + "tsconfig-paths": "^4.2.0", + "tsyringe": "^4.8.0", "typedi": "^0.10.0", - "typeorm": "^0.2.31", - "typeorm-typedi-extensions": "^0.4.1", - "typescript": "~4.2.2" + "typeorm": "^0.3.19", + "typescript": "^5.3.3", + "typescript-transform-paths": "^3.4.6", + "typescript-transformer-esm": "^1.1.0", + "yargs": "^17.7.2" + }, + "engines": { + "node": ">= 18.12.0" }, + "peerDependencies": { + "class-validator": ">=0.14.0", + "graphql": "^16.8.1", + "graphql-scalars": "^1.22.4" + }, + "peerDependenciesMeta": { + "class-validator": { + "optional": true + } + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, "engines": { - "node": ">= 10.3" + "node": ">=0.10.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@antfu/utils": { + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.7.tgz", + "integrity": "sha512-gFPqTG7otEJ8uP6wrhDv6mqwGWYZKNvAcCq6u9hOj0c+IKCEsY4L1oC9trPq2SaWIzAfHvqfBDxF591JkMf+kg==", + "dev": true, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typegraphql" + "url": "https://github.com/sponsors/antfu" + } + }, + "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==", + "dev": true, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/composition": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@apollo/composition/-/composition-2.7.1.tgz", + "integrity": "sha512-ZcFSSpHNg3eFX+yjV0hyblMdJiMfPYNOORAmH14YAHOnFT2UITQaxtbt3d6LZiyEuw5ugx3jKE+eoiX+LdLfvw==", + "dev": true, + "dependencies": { + "@apollo/federation-internals": "2.7.1", + "@apollo/query-graphs": "2.7.1" + }, + "engines": { + "node": ">=14.15.0" }, "peerDependencies": { - "class-validator": ">=0.12.0", - "graphql": "^15.5.0" + "graphql": "^16.5.0" } }, - "node_modules/@apollo/federation": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/@apollo/federation/-/federation-0.21.2.tgz", - "integrity": "sha512-ZQ2TcRv7QO/84+SKFQrhppg+s0EcwBfSPT27DcoLYfEj8tsNjbUmsyxiH5CE2NJtG0F8y520nIM8tQ9wUrePsg==", + "node_modules/@apollo/composition/node_modules/@apollo/federation-internals": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@apollo/federation-internals/-/federation-internals-2.7.1.tgz", + "integrity": "sha512-xJPF8qrqzYxY2pXLODihMbCo7dyNwiAIlWzJ4fF3G6cuje1HD9Ke3l8qAPooeQLb2OqRoHhtc+hhwMDc8AOYoQ==", "dev": true, "dependencies": { - "apollo-graphql": "^0.6.0", - "lodash.xorby": "^4.7.0" + "@types/uuid": "^9.0.0", + "chalk": "^4.1.0", + "js-levenshtein": "^1.1.6", + "uuid": "^9.0.0" }, "engines": { - "node": ">=12.13.0 <15.0" + "node": ">=14.15.0" }, "peerDependencies": { - "graphql": "^14.5.0 || ^15.0.0" + "graphql": "^16.5.0" } }, "node_modules/@apollo/gateway": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/@apollo/gateway/-/gateway-0.23.2.tgz", - "integrity": "sha512-WGrlAzvBfvWGnwajlUowde2VXdkH5EtqgOLnwdYCB7FVMkLT8B/Qj6ePxK+Kbwonz7lcnEvNaL4rvF2ICGudWg==", - "dev": true, - "dependencies": { - "@apollo/federation": "^0.21.2", - "@apollo/query-planner-wasm": "^0.1.2", - "@types/node-fetch": "2.5.4", - "apollo-graphql": "^0.6.0", - "apollo-reporting-protobuf": "^0.6.0", - "apollo-server-caching": "^0.5.3", - "apollo-server-core": "^2.19.2", - "apollo-server-env": "^3.0.0", - "apollo-server-errors": "^2.4.2", - "apollo-server-types": "^0.6.3", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@apollo/gateway/-/gateway-2.7.1.tgz", + "integrity": "sha512-3jOk669H7uNmBlRI88rXZulSb2V2UORmNvAcHr5XfBxW0cZ59xWPQJ3Xoc6QILZ7DkiGPW1lLqJ+qgI9RBHzyg==", + "dev": true, + "dependencies": { + "@apollo/composition": "2.7.1", + "@apollo/federation-internals": "2.7.1", + "@apollo/query-planner": "2.7.1", + "@apollo/server-gateway-interface": "^1.1.0", + "@apollo/usage-reporting-protobuf": "^4.1.0", + "@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", + "@josephg/resolvable": "^1.0.1", + "@opentelemetry/api": "^1.0.1", + "@types/node-fetch": "^2.6.2", + "async-retry": "^1.3.3", "loglevel": "^1.6.1", - "make-fetch-happen": "^8.0.0", - "pretty-format": "^26.0.0" + "make-fetch-happen": "^11.0.0", + "node-abort-controller": "^3.0.1", + "node-fetch": "^2.6.7" + }, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "graphql": "^16.5.0" + } + }, + "node_modules/@apollo/gateway/node_modules/@apollo/federation-internals": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@apollo/federation-internals/-/federation-internals-2.7.1.tgz", + "integrity": "sha512-xJPF8qrqzYxY2pXLODihMbCo7dyNwiAIlWzJ4fF3G6cuje1HD9Ke3l8qAPooeQLb2OqRoHhtc+hhwMDc8AOYoQ==", + "dev": true, + "dependencies": { + "@types/uuid": "^9.0.0", + "chalk": "^4.1.0", + "js-levenshtein": "^1.1.6", + "uuid": "^9.0.0" }, "engines": { - "node": ">=12.13.0 <15.0" + "node": ">=14.15.0" }, "peerDependencies": { - "graphql": "^14.5.0 || ^15.0.0" + "graphql": "^16.5.0" } }, "node_modules/@apollo/protobufjs": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.0.5.tgz", - "integrity": "sha512-ZtyaBH1icCgqwIGb3zrtopV2D5Q8yxibkJzlaViM08eOhTQc7rACdYu0pfORFfhllvdMZ3aq69vifYHszY4gNA==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.7.tgz", + "integrity": "sha512-Lahx5zntHPZia35myYDBRuF58tlwPskwHc5CWBZC/4bMKB6siTBWwtMrkqXcsNwQiFSzSx5hKdRPUmemrEp3Gg==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -138,7 +253,6 @@ "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/long": "^4.0.0", - "@types/node": "^10.1.0", "long": "^4.0.0" }, "bin": { @@ -146,389 +260,736 @@ "apollo-pbts": "bin/pbts" } }, - "node_modules/@apollo/protobufjs/node_modules/@types/node": { - "version": "10.17.54", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.54.tgz", - "integrity": "sha512-c8Lm7+hXdSPmWH4B9z/P/xIXhFK3mCQin4yCYMd2p1qpMG5AfgyJuYZ+3q2dT7qLiMMMGMd5dnkFpdqJARlvtQ==", - "dev": true - }, - "node_modules/@apollo/query-planner-wasm": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@apollo/query-planner-wasm/-/query-planner-wasm-0.1.2.tgz", - "integrity": "sha512-djHcJXTOEZZec0M8ZhK3rGu/ZEAilgr6mu55X7JIxEJEI7Sq57e4r4Lbsfffx+fVxjDb2BK4mabsPHR4vVnG0Q==", - "dev": true - }, - "node_modules/@apollographql/apollo-tools": { - "version": "0.4.9", - "resolved": "https://registry.npmjs.org/@apollographql/apollo-tools/-/apollo-tools-0.4.9.tgz", - "integrity": "sha512-M50pk8oo3CGTu4waGOklIX3YtTZoPfWG9K/G9WB8NpyQGA1OwYTiBFv94XqUtKElTDoFwoMXpMQd3Wy5dINvxA==", + "node_modules/@apollo/query-graphs": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@apollo/query-graphs/-/query-graphs-2.7.1.tgz", + "integrity": "sha512-hixjS4J3De1UyOL81aLiyJxIUKy3rEVbR4VmbjhnH+4lX2F94c94LMuXOiC6p1p+txM6iOnqeOO5FBKMupSCrg==", "dev": true, "dependencies": { - "apollo-env": "^0.6.6" + "@apollo/federation-internals": "2.7.1", + "deep-equal": "^2.0.5", + "ts-graphviz": "^1.5.4", + "uuid": "^9.0.0" }, "engines": { - "node": ">=8", - "npm": ">=6" - } - }, - "node_modules/@apollographql/graphql-playground-html": { - "version": "1.6.26", - "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.26.tgz", - "integrity": "sha512-XAwXOIab51QyhBxnxySdK3nuMEUohhDsHQ5Rbco/V1vjlP75zZ0ZLHD9dTpXTN8uxKxopb2lUvJTq+M4g2Q0HQ==", - "dev": true, - "dependencies": { - "xss": "^1.0.6" + "node": ">=14.15.0" + }, + "peerDependencies": { + "graphql": "^16.5.0" } }, - "node_modules/@apollographql/graphql-upload-8-fork": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/@apollographql/graphql-upload-8-fork/-/graphql-upload-8-fork-8.1.3.tgz", - "integrity": "sha512-ssOPUT7euLqDXcdVv3Qs4LoL4BPtfermW1IOouaqEmj36TpHYDmYDIbKoSQxikd9vtMumFnP87OybH7sC9fJ6g==", + "node_modules/@apollo/query-graphs/node_modules/@apollo/federation-internals": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@apollo/federation-internals/-/federation-internals-2.7.1.tgz", + "integrity": "sha512-xJPF8qrqzYxY2pXLODihMbCo7dyNwiAIlWzJ4fF3G6cuje1HD9Ke3l8qAPooeQLb2OqRoHhtc+hhwMDc8AOYoQ==", "dev": true, "dependencies": { - "@types/express": "*", - "@types/fs-capacitor": "*", - "@types/koa": "*", - "busboy": "^0.3.1", - "fs-capacitor": "^2.0.4", - "http-errors": "^1.7.3", - "object-path": "^0.11.4" + "@types/uuid": "^9.0.0", + "chalk": "^4.1.0", + "js-levenshtein": "^1.1.6", + "uuid": "^9.0.0" }, "engines": { - "node": ">=8.5" + "node": ">=14.15.0" }, "peerDependencies": { - "graphql": "0.13.1 - 15" + "graphql": "^16.5.0" } }, - "node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "node_modules/@apollo/query-planner": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@apollo/query-planner/-/query-planner-2.7.1.tgz", + "integrity": "sha512-OXw3LuabAiWGwuXYDxmp3tRwi2rxPnifGRhWyDtGAX4ZJHeLHhcIyPE3BK/Ly0nAxOoNRJWhgjK0dxbb7QPa3Q==", "dev": true, "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "node_modules/@babel/core": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.10.tgz", - "integrity": "sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.10", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helpers": "^7.12.5", - "@babel/parser": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.10", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.19", - "semver": "^5.4.1", - "source-map": "^0.5.0" + "@apollo/federation-internals": "2.7.1", + "@apollo/query-graphs": "2.7.1", + "@apollo/utils.keyvaluecache": "^2.1.0", + "chalk": "^4.1.0", + "deep-equal": "^2.0.5", + "pretty-format": "^29.0.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=14.15.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" + "peerDependencies": { + "graphql": "^16.5.0" } }, - "node_modules/@babel/core/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "node_modules/@apollo/query-planner/node_modules/@apollo/federation-internals": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@apollo/federation-internals/-/federation-internals-2.7.1.tgz", + "integrity": "sha512-xJPF8qrqzYxY2pXLODihMbCo7dyNwiAIlWzJ4fF3G6cuje1HD9Ke3l8qAPooeQLb2OqRoHhtc+hhwMDc8AOYoQ==", "dev": true, "dependencies": { - "ms": "2.1.2" + "@types/uuid": "^9.0.0", + "chalk": "^4.1.0", + "js-levenshtein": "^1.1.6", + "uuid": "^9.0.0" }, "engines": { - "node": ">=6.0" + "node": ">=14.15.0" + }, + "peerDependencies": { + "graphql": "^16.5.0" + } + }, + "node_modules/@apollo/server": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@apollo/server/-/server-4.10.0.tgz", + "integrity": "sha512-pLx//lZ/pvUfWL9G8Np8+y3ujc0pYc8U7dwD6ztt9FAw8NmCPzPaDzlXLBAjGU6WnkqVBOnz8b3dOwRNjLYSUA==", + "dev": true, + "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" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@babel/core/node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/@babel/core/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "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/@babel/core/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=14.16.0" + }, + "peerDependencies": { + "graphql": "^16.6.0" } }, - "node_modules/@babel/generator": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", - "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", + "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==", "dev": true, "dependencies": { - "@babel/types": "^7.12.11", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" + "@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/@babel/generator/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "node_modules/@apollo/server-plugin-response-cache": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@apollo/server-plugin-response-cache/-/server-plugin-response-cache-4.1.3.tgz", + "integrity": "sha512-8WaP4Xo9GGIbWn4ZG/TlYKZLo/YI8tuORvxzLOKnZa3EqUvt7iTCGHX491dWNiGkm93VgDDdo5r0WEvLDdHSmQ==", "dev": true, + "dependencies": { + "@apollo/utils.createhash": "^2.0.0", + "@apollo/utils.keyvaluecache": "^2.1.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=14.16.0" + }, + "peerDependencies": { + "@apollo/server": "^4.0.1", + "graphql": "^16.6.0" } }, - "node_modules/@babel/helper-function-name": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", - "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "node_modules/@apollo/server/node_modules/@graphql-tools/merge": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.4.2.tgz", + "integrity": "sha512-XbrHAaj8yDuINph+sAfuq3QCZ/tKblrTLOpirK0+CAgNlZUCHs0Fa+xtMUURgwCVThLle1AF7svJCxFizygLsw==", "dev": true, "dependencies": { - "@babel/helper-get-function-arity": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/types": "^7.12.11" + "@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/@babel/helper-get-function-arity": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", - "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "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==", "dev": true, "dependencies": { - "@babel/types": "^7.12.10" + "@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/@babel/helper-member-expression-to-functions": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", - "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", + "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==", "dev": true, "dependencies": { - "@babel/types": "^7.12.7" + "@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/@babel/helper-module-imports": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", - "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", + "node_modules/@apollo/subgraph": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@apollo/subgraph/-/subgraph-2.7.1.tgz", + "integrity": "sha512-JYxMOnBbPbTJ3ySUyi4tKFOHtAkMy5pzyzskGyky0aqXWCqLm2Vd92kmmtcbAtXAvkaRVGT8ONlTHAw5lvVa0Q==", "dev": true, "dependencies": { - "@babel/types": "^7.12.5" + "@apollo/cache-control-types": "^1.0.2", + "@apollo/federation-internals": "2.7.1" + }, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "graphql": "^16.5.0" } }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", - "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", + "node_modules/@apollo/subgraph/node_modules/@apollo/federation-internals": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@apollo/federation-internals/-/federation-internals-2.7.1.tgz", + "integrity": "sha512-xJPF8qrqzYxY2pXLODihMbCo7dyNwiAIlWzJ4fF3G6cuje1HD9Ke3l8qAPooeQLb2OqRoHhtc+hhwMDc8AOYoQ==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.12.1", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-simple-access": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/helper-validator-identifier": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.1", - "@babel/types": "^7.12.1", - "lodash": "^4.17.19" + "@types/uuid": "^9.0.0", + "chalk": "^4.1.0", + "js-levenshtein": "^1.1.6", + "uuid": "^9.0.0" + }, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "graphql": "^16.5.0" } }, - "node_modules/@babel/helper-module-transforms/node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", - "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", + "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==", "dev": true, "dependencies": { - "@babel/types": "^7.12.10" + "@apollo/protobufjs": "1.2.7" } }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", - "dev": true - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", - "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "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==", "dev": true, "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.12.7", - "@babel/helper-optimise-call-expression": "^7.12.10", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.11" + "@apollo/utils.isnodelike": "^2.0.1", + "sha.js": "^2.4.11" + }, + "engines": { + "node": ">=14" } }, - "node_modules/@babel/helper-simple-access": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", - "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", + "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==", "dev": true, - "dependencies": { - "@babel/types": "^7.12.1" + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" } }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", - "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "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==", "dev": true, - "dependencies": { - "@babel/types": "^7.12.11" + "engines": { + "node": ">=14" } }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true - }, - "node_modules/@babel/helpers": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", - "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", + "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==", "dev": true, - "dependencies": { - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.5", - "@babel/types": "^7.12.5" + "engines": { + "node": ">=14" } }, - "node_modules/@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "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==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.10.4", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" + "@apollo/utils.logger": "^2.0.1", + "lru-cache": "^7.14.1" + }, + "engines": { + "node": ">=14" } }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "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==", "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, "engines": { - "node": ">=4" + "node": ">=14" } }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "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==", "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "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==", + "dev": true, "engines": { - "node": ">=4" + "node": ">=14" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" } }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "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==", "dev": true, "dependencies": { - "color-name": "1.1.3" + "lodash.sortby": "^4.7.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" } }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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==", "dev": true, "engines": { - "node": ">=4" + "node": ">=14" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" } }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/@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==", "dev": true, "dependencies": { - "has-flag": "^3.0.0" + "@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": ">=4" + "node": ">=14" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" } }, - "node_modules/@babel/parser": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "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==", "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, "engines": { - "node": ">=6.0.0" + "node": ">=14" } }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "node_modules/@babel/code-frame": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", + "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/highlight": "^7.22.5" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", + "node_modules/@babel/compat-data": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.6.tgz", + "integrity": "sha512-29tfsWTq2Ftu7MXmimyC0C5FDZv5DYxOZkh3XD3+QW4V/BYuv/LyEsjj3c0hqedEaDt6DBfDvexMKU8YevdqFg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.22.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.8.tgz", + "integrity": "sha512-75+KxFB4CZqYRXjx4NlR4J7yGvKumBuZTmV4NV6v09dVXXkuYVYLT68N6HCzLvfJ+fWCxQsntNzKwwIXL4bHnw==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.5", + "@babel/generator": "^7.22.7", + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helpers": "^7.22.6", + "@babel/parser": "^7.22.7", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.8", + "@babel/types": "^7.22.5", + "@nicolo-ribaudo/semver-v6": "^6.3.3", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/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/@babel/generator": { + "version": "7.22.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.7.tgz", + "integrity": "sha512-p+jPjMG+SI8yvIaxGgeW24u7q9+5+TGpZh8/CuB7RhBKd7RCy8FayNEFNNKrNK/eUcY/4ExQqLmyrvBXKsIcwQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.6.tgz", + "integrity": "sha512-534sYEqWD9VfUm3IPn2SLcH4Q3P86XL+QvqdC7ZsFrzyyPF3T4XGiVghF6PTYNdWg6pXuoqXxNQAhbYeEInTzA==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-validator-option": "^7.22.5", + "@nicolo-ribaudo/semver-v6": "^6.3.3", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.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==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "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==", + "dev": true + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", + "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", + "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.5", + "@babel/types": "^7.22.5" + }, + "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==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", + "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz", + "integrity": "sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "dev": true, + "engines": { + "node": ">=6.9.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==", + "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==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", + "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.6.tgz", + "integrity": "sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.6", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", + "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/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==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/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==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.22.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.7.tgz", + "integrity": "sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, @@ -540,12 +1001,12 @@ } }, "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz", - "integrity": "sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA==", + "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.10.4" + "@babel/helper-plugin-utils": "^7.12.13" }, "peerDependencies": { "@babel/core": "^7.0.0-0" @@ -575,6 +1036,21 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", + "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", + "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-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", @@ -648,2734 +1124,3351 @@ } }, "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz", - "integrity": "sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A==", + "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.10.4" + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/template": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", - "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", + "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.12.7", - "@babel/types": "^7.12.7" + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/traverse": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", - "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "node_modules/@babel/template": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", + "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.12.11", - "@babel/generator": "^7.12.11", - "@babel/helper-function-name": "^7.12.11", - "@babel/helper-split-export-declaration": "^7.12.11", - "@babel/parser": "^7.12.11", - "@babel/types": "^7.12.12", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.19" + "@babel/code-frame": "^7.22.5", + "@babel/parser": "^7.22.5", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@babel/traverse/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" + "node_modules/@babel/traverse": { + "version": "7.22.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.8.tgz", + "integrity": "sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.5", + "@babel/generator": "^7.22.7", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.22.7", + "@babel/types": "^7.22.5", + "debug": "^4.1.0", + "globals": "^11.1.0" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=6.9.0" } }, - "node_modules/@babel/traverse/node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/@babel/traverse/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } }, "node_modules/@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", + "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@babel/types/node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "node_modules/@cnakazawa/watch": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", - "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "node_modules/@cspell/cspell-bundled-dicts": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-8.3.2.tgz", + "integrity": "sha512-3ubOgz1/MDixJbq//0rQ2omB3cSdhVJDviERZeiREGz4HOq84aaK1Fqbw5SjNZHvhpoq+AYXm6kJbIAH8YhKgg==", + "dev": true, + "dependencies": { + "@cspell/dict-ada": "^4.0.2", + "@cspell/dict-aws": "^4.0.1", + "@cspell/dict-bash": "^4.1.3", + "@cspell/dict-companies": "^3.0.29", + "@cspell/dict-cpp": "^5.0.10", + "@cspell/dict-cryptocurrencies": "^5.0.0", + "@cspell/dict-csharp": "^4.0.2", + "@cspell/dict-css": "^4.0.12", + "@cspell/dict-dart": "^2.0.3", + "@cspell/dict-django": "^4.1.0", + "@cspell/dict-docker": "^1.1.7", + "@cspell/dict-dotnet": "^5.0.0", + "@cspell/dict-elixir": "^4.0.3", + "@cspell/dict-en_us": "^4.3.13", + "@cspell/dict-en-common-misspellings": "^2.0.0", + "@cspell/dict-en-gb": "1.1.33", + "@cspell/dict-filetypes": "^3.0.3", + "@cspell/dict-fonts": "^4.0.0", + "@cspell/dict-fsharp": "^1.0.1", + "@cspell/dict-fullstack": "^3.1.5", + "@cspell/dict-gaming-terms": "^1.0.4", + "@cspell/dict-git": "^3.0.0", + "@cspell/dict-golang": "^6.0.5", + "@cspell/dict-haskell": "^4.0.1", + "@cspell/dict-html": "^4.0.5", + "@cspell/dict-html-symbol-entities": "^4.0.0", + "@cspell/dict-java": "^5.0.6", + "@cspell/dict-k8s": "^1.0.2", + "@cspell/dict-latex": "^4.0.0", + "@cspell/dict-lorem-ipsum": "^4.0.0", + "@cspell/dict-lua": "^4.0.3", + "@cspell/dict-makefile": "^1.0.0", + "@cspell/dict-node": "^4.0.3", + "@cspell/dict-npm": "^5.0.14", + "@cspell/dict-php": "^4.0.5", + "@cspell/dict-powershell": "^5.0.3", + "@cspell/dict-public-licenses": "^2.0.5", + "@cspell/dict-python": "^4.1.11", + "@cspell/dict-r": "^2.0.1", + "@cspell/dict-ruby": "^5.0.2", + "@cspell/dict-rust": "^4.0.1", + "@cspell/dict-scala": "^5.0.0", + "@cspell/dict-software-terms": "^3.3.15", + "@cspell/dict-sql": "^2.1.3", + "@cspell/dict-svelte": "^1.0.2", + "@cspell/dict-swift": "^2.0.1", + "@cspell/dict-typescript": "^3.1.2", + "@cspell/dict-vue": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@cspell/cspell-json-reporter": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@cspell/cspell-json-reporter/-/cspell-json-reporter-8.7.0.tgz", + "integrity": "sha512-LTQPEvXvCqnc+ok9WXpSISZyt4/nGse9fVEM430g0BpGzKpt3RMx49B8uasvvnanzCuikaW9+wFLmwgvraERhA==", + "dev": true, + "dependencies": { + "@cspell/cspell-types": "8.7.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@cspell/cspell-json-reporter/node_modules/@cspell/cspell-types": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@cspell/cspell-types/-/cspell-types-8.7.0.tgz", + "integrity": "sha512-Rb+LCE5I9JEb/LE8nSViVSF8z1CWv/z4mPBIG37VMa7aUx2gAQa6gJekNfpY9YZiMzx4Tv3gDujN80ytks4pGA==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@cspell/cspell-pipe": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/@cspell/cspell-pipe/-/cspell-pipe-8.3.2.tgz", + "integrity": "sha512-GZmDwvQGOjQi3IjD4k9xXeVTDANczksOsgVKb3v2QZk9mR4Qj8c6Uarjd4AgSiIhu/wBliJfzr5rWFJu4X2VfQ==", "dev": true, - "dependencies": { - "exec-sh": "^0.3.2", - "minimist": "^1.2.0" - }, - "bin": { - "watch": "cli.js" - }, "engines": { - "node": ">=0.1.95" + "node": ">=18" } }, - "node_modules/@graphql-modules/core": { - "version": "0.7.13", - "resolved": "https://registry.npmjs.org/@graphql-modules/core/-/core-0.7.13.tgz", - "integrity": "sha512-csBpOPmk5UdETC5UeN8wqacNMzOrfiMkdEUMixPuQ7/+i0wrvNR1k4FGy97DVb09YGrNhpwF3pphlc/2warhLQ==", + "node_modules/@cspell/cspell-resolver": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/@cspell/cspell-resolver/-/cspell-resolver-8.3.2.tgz", + "integrity": "sha512-w2Tmb95bzdEz9L4W5qvsP5raZbyEzKL7N2ksU/+yh8NEJcTuExmAl/nMnb3aIk7m2b+kPHnMOcJuwfUMLmyv4A==", "dev": true, "dependencies": { - "@graphql-modules/di": "0.7.13", - "apollo-server-caching": "0.5.0", - "graphql-toolkit": "0.5.16", - "tslib": "1.10.0" + "global-directory": "^4.0.1" }, - "peerDependencies": { - "graphql": "^14.1.1" + "engines": { + "node": ">=18" } }, - "node_modules/@graphql-modules/core/node_modules/@graphql-modules/di": { - "version": "0.7.13", - "resolved": "https://registry.npmjs.org/@graphql-modules/di/-/di-0.7.13.tgz", - "integrity": "sha512-/WEFjDcrSnXfUS1IA8FwAnI+KQSB5FoBYYlvSQ6hUzD5WYk0Ge34Xt2JVUAlhmRDlgpHlErlFLW6ZhTsKA22/Q==", + "node_modules/@cspell/cspell-service-bus": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/@cspell/cspell-service-bus/-/cspell-service-bus-8.3.2.tgz", + "integrity": "sha512-skTHNyVi74//W/O+f4IauDhm6twA9S2whkylonsIzPxEl4Pn3y2ZEMXNki/MWUwZfDIzKKSxlcREH61g7zCvhg==", "dev": true, - "dependencies": { - "events": "3.0.0", - "tslib": "1.10.0" - }, - "peerDependencies": { - "reflect-metadata": "^0.1.12" + "engines": { + "node": ">=18" } }, - "node_modules/@graphql-modules/core/node_modules/@kamilkisiela/graphql-tools": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@kamilkisiela/graphql-tools/-/graphql-tools-4.0.6.tgz", - "integrity": "sha512-IPWa+dOFCE4zaCsrJrAMp7yWXnfOZLNhqoMEOmn958WkLM0mmsDc/W/Rh7/7xopIT6P0oizb6/N1iH5HnNXOUA==", + "node_modules/@cspell/cspell-types": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/@cspell/cspell-types/-/cspell-types-8.3.2.tgz", + "integrity": "sha512-qS/gWd9ItOrN6ZX5pwC9lJjnBoyiAyhxYq0GUXuV892LQvwrBmECGk6KhsA1lPW7JJS7o57YTAS1jmXnmXMEpg==", "dev": true, - "dependencies": { - "apollo-link": "^1.2.3", - "apollo-utilities": "^1.0.1", - "deprecated-decorator": "^0.1.6", - "iterall": "^1.1.3", - "uuid": "^3.1.0" - }, - "peerDependencies": { - "graphql": "^0.13.0 || ^14.0.0" + "engines": { + "node": ">=18" } }, - "node_modules/@graphql-modules/core/node_modules/@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "node_modules/@cspell/dict-ada": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@cspell/dict-ada/-/dict-ada-4.0.2.tgz", + "integrity": "sha512-0kENOWQeHjUlfyId/aCM/mKXtkEgV0Zu2RhUXCBr4hHo9F9vph+Uu8Ww2b0i5a4ZixoIkudGA+eJvyxrG1jUpA==", + "dev": true + }, + "node_modules/@cspell/dict-aws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-aws/-/dict-aws-4.0.1.tgz", + "integrity": "sha512-NXO+kTPQGqaaJKa4kO92NAXoqS+i99dQzf3/L1BxxWVSBS3/k1f3uhmqIh7Crb/n22W793lOm0D9x952BFga3Q==", + "dev": true + }, + "node_modules/@cspell/dict-bash": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-bash/-/dict-bash-4.1.3.tgz", + "integrity": "sha512-tOdI3QVJDbQSwPjUkOiQFhYcu2eedmX/PtEpVWg0aFps/r6AyjUQINtTgpqMYnYuq8O1QUIQqnpx21aovcgZCw==", + "dev": true + }, + "node_modules/@cspell/dict-companies": { + "version": "3.0.31", + "resolved": "https://registry.npmjs.org/@cspell/dict-companies/-/dict-companies-3.0.31.tgz", + "integrity": "sha512-hKVpV/lcGKP4/DpEPS8P4osPvFH/YVLJaDn9cBIOH6/HSmL5LbFgJNKpMGaYRbhm2FEX56MKE3yn/MNeNYuesQ==", + "dev": true + }, + "node_modules/@cspell/dict-cpp": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-cpp/-/dict-cpp-5.1.3.tgz", + "integrity": "sha512-sqnriXRAInZH9W75C+APBh6dtben9filPqVbIsiRMUXGg+s02ekz0z6LbS7kXeJ5mD2qXoMLBrv13qH2eIwutQ==", + "dev": true + }, + "node_modules/@cspell/dict-cryptocurrencies": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-cryptocurrencies/-/dict-cryptocurrencies-5.0.0.tgz", + "integrity": "sha512-Z4ARIw5+bvmShL+4ZrhDzGhnc9znaAGHOEMaB/GURdS/jdoreEDY34wdN0NtdLHDO5KO7GduZnZyqGdRoiSmYA==", + "dev": true + }, + "node_modules/@cspell/dict-csharp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@cspell/dict-csharp/-/dict-csharp-4.0.2.tgz", + "integrity": "sha512-1JMofhLK+4p4KairF75D3A924m5ERMgd1GvzhwK2geuYgd2ZKuGW72gvXpIV7aGf52E3Uu1kDXxxGAiZ5uVG7g==", + "dev": true + }, + "node_modules/@cspell/dict-css": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/@cspell/dict-css/-/dict-css-4.0.12.tgz", + "integrity": "sha512-vGBgPM92MkHQF5/2jsWcnaahOZ+C6OE/fPvd5ScBP72oFY9tn5GLuomcyO0z8vWCr2e0nUSX1OGimPtcQAlvSw==", + "dev": true + }, + "node_modules/@cspell/dict-dart": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-dart/-/dict-dart-2.0.3.tgz", + "integrity": "sha512-cLkwo1KT5CJY5N5RJVHks2genFkNCl/WLfj+0fFjqNR+tk3tBI1LY7ldr9piCtSFSm4x9pO1x6IV3kRUY1lLiw==", + "dev": true + }, + "node_modules/@cspell/dict-data-science": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@cspell/dict-data-science/-/dict-data-science-1.0.11.tgz", + "integrity": "sha512-TaHAZRVe0Zlcc3C23StZqqbzC0NrodRwoSAc8dis+5qLeLLnOCtagYQeROQvDlcDg3X/VVEO9Whh4W/z4PAmYQ==", + "dev": true + }, + "node_modules/@cspell/dict-django": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-django/-/dict-django-4.1.0.tgz", + "integrity": "sha512-bKJ4gPyrf+1c78Z0Oc4trEB9MuhcB+Yg+uTTWsvhY6O2ncFYbB/LbEZfqhfmmuK/XJJixXfI1laF2zicyf+l0w==", + "dev": true + }, + "node_modules/@cspell/dict-docker": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@cspell/dict-docker/-/dict-docker-1.1.7.tgz", + "integrity": "sha512-XlXHAr822euV36GGsl2J1CkBIVg3fZ6879ZOg5dxTIssuhUOCiV2BuzKZmt6aIFmcdPmR14+9i9Xq+3zuxeX0A==", + "dev": true + }, + "node_modules/@cspell/dict-dotnet": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-dotnet/-/dict-dotnet-5.0.0.tgz", + "integrity": "sha512-EOwGd533v47aP5QYV8GlSSKkmM9Eq8P3G/eBzSpH3Nl2+IneDOYOBLEUraHuiCtnOkNsz0xtZHArYhAB2bHWAw==", + "dev": true + }, + "node_modules/@cspell/dict-elixir": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-elixir/-/dict-elixir-4.0.3.tgz", + "integrity": "sha512-g+uKLWvOp9IEZvrIvBPTr/oaO6619uH/wyqypqvwpmnmpjcfi8+/hqZH8YNKt15oviK8k4CkINIqNhyndG9d9Q==", + "dev": true + }, + "node_modules/@cspell/dict-en_us": { + "version": "4.3.19", + "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.3.19.tgz", + "integrity": "sha512-tHcXdkmm0t9LlRct1vgu3+h0KW/wlXCInkTiR4D/rl730q1zu2qVEgiy1saMiTUSNmdu7Hiy+Mhb+1braVqnZQ==", + "dev": true + }, + "node_modules/@cspell/dict-en-common-misspellings": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-en-common-misspellings/-/dict-en-common-misspellings-2.0.0.tgz", + "integrity": "sha512-NOg8dlv37/YqLkCfBs5OXeJm/Wcfb/CzeOmOZJ2ZXRuxwsNuolb4TREUce0yAXRqMhawahY5TSDRJJBgKjBOdw==", + "dev": true + }, + "node_modules/@cspell/dict-en-gb": { + "version": "1.1.33", + "resolved": "https://registry.npmjs.org/@cspell/dict-en-gb/-/dict-en-gb-1.1.33.tgz", + "integrity": "sha512-tKSSUf9BJEV+GJQAYGw5e+ouhEe2ZXE620S7BLKe3ZmpnjlNG9JqlnaBhkIMxKnNFkLY2BP/EARzw31AZnOv4g==", + "dev": true + }, + "node_modules/@cspell/dict-filetypes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-filetypes/-/dict-filetypes-3.0.3.tgz", + "integrity": "sha512-J9UP+qwwBLfOQ8Qg9tAsKtSY/WWmjj21uj6zXTI9hRLD1eG1uUOLcfVovAmtmVqUWziPSKMr87F6SXI3xmJXgw==", + "dev": true + }, + "node_modules/@cspell/dict-fonts": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-fonts/-/dict-fonts-4.0.0.tgz", + "integrity": "sha512-t9V4GeN/m517UZn63kZPUYP3OQg5f0OBLSd3Md5CU3eH1IFogSvTzHHnz4Wqqbv8NNRiBZ3HfdY/pqREZ6br3Q==", + "dev": true + }, + "node_modules/@cspell/dict-fsharp": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-fsharp/-/dict-fsharp-1.0.1.tgz", + "integrity": "sha512-23xyPcD+j+NnqOjRHgW3IU7Li912SX9wmeefcY0QxukbAxJ/vAN4rBpjSwwYZeQPAn3fxdfdNZs03fg+UM+4yQ==", + "dev": true + }, + "node_modules/@cspell/dict-fullstack": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@cspell/dict-fullstack/-/dict-fullstack-3.1.5.tgz", + "integrity": "sha512-6ppvo1dkXUZ3fbYn/wwzERxCa76RtDDl5Afzv2lijLoijGGUw5yYdLBKJnx8PJBGNLh829X352ftE7BElG4leA==", + "dev": true + }, + "node_modules/@cspell/dict-gaming-terms": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@cspell/dict-gaming-terms/-/dict-gaming-terms-1.0.5.tgz", + "integrity": "sha512-C3riccZDD3d9caJQQs1+MPfrUrQ+0KHdlj9iUR1QD92FgTOF6UxoBpvHUUZ9YSezslcmpFQK4xQQ5FUGS7uWfw==", + "dev": true + }, + "node_modules/@cspell/dict-git": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-git/-/dict-git-3.0.0.tgz", + "integrity": "sha512-simGS/lIiXbEaqJu9E2VPoYW1OTC2xrwPPXNXFMa2uo/50av56qOuaxDrZ5eH1LidFXwoc8HROCHYeKoNrDLSw==", + "dev": true + }, + "node_modules/@cspell/dict-golang": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/@cspell/dict-golang/-/dict-golang-6.0.5.tgz", + "integrity": "sha512-w4mEqGz4/wV+BBljLxduFNkMrd3rstBNDXmoX5kD4UTzIb4Sy0QybWCtg2iVT+R0KWiRRA56QKOvBsgXiddksA==", + "dev": true + }, + "node_modules/@cspell/dict-haskell": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-haskell/-/dict-haskell-4.0.1.tgz", + "integrity": "sha512-uRrl65mGrOmwT7NxspB4xKXFUenNC7IikmpRZW8Uzqbqcu7ZRCUfstuVH7T1rmjRgRkjcIjE4PC11luDou4wEQ==", + "dev": true + }, + "node_modules/@cspell/dict-html": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@cspell/dict-html/-/dict-html-4.0.5.tgz", + "integrity": "sha512-p0brEnRybzSSWi8sGbuVEf7jSTDmXPx7XhQUb5bgG6b54uj+Z0Qf0V2n8b/LWwIPJNd1GygaO9l8k3HTCy1h4w==", + "dev": true + }, + "node_modules/@cspell/dict-html-symbol-entities": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-html-symbol-entities/-/dict-html-symbol-entities-4.0.0.tgz", + "integrity": "sha512-HGRu+48ErJjoweR5IbcixxETRewrBb0uxQBd6xFGcxbEYCX8CnQFTAmKI5xNaIt2PKaZiJH3ijodGSqbKdsxhw==", + "dev": true + }, + "node_modules/@cspell/dict-java": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@cspell/dict-java/-/dict-java-5.0.6.tgz", + "integrity": "sha512-kdE4AHHHrixyZ5p6zyms1SLoYpaJarPxrz8Tveo6gddszBVVwIUZ+JkQE1bWNLK740GWzIXdkznpUfw1hP9nXw==", + "dev": true + }, + "node_modules/@cspell/dict-julia": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-julia/-/dict-julia-1.0.1.tgz", + "integrity": "sha512-4JsCLCRhhLMLiaHpmR7zHFjj1qOauzDI5ZzCNQS31TUMfsOo26jAKDfo0jljFAKgw5M2fEG7sKr8IlPpQAYrmQ==", + "dev": true + }, + "node_modules/@cspell/dict-k8s": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@cspell/dict-k8s/-/dict-k8s-1.0.2.tgz", + "integrity": "sha512-tLT7gZpNPnGa+IIFvK9SP1LrSpPpJ94a/DulzAPOb1Q2UBFwdpFd82UWhio0RNShduvKG/WiMZf/wGl98pn+VQ==", + "dev": true + }, + "node_modules/@cspell/dict-latex": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-latex/-/dict-latex-4.0.0.tgz", + "integrity": "sha512-LPY4y6D5oI7D3d+5JMJHK/wxYTQa2lJMSNxps2JtuF8hbAnBQb3igoWEjEbIbRRH1XBM0X8dQqemnjQNCiAtxQ==", + "dev": true + }, + "node_modules/@cspell/dict-lorem-ipsum": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-lorem-ipsum/-/dict-lorem-ipsum-4.0.0.tgz", + "integrity": "sha512-1l3yjfNvMzZPibW8A7mQU4kTozwVZVw0AvFEdy+NcqtbxH+TvbSkNMqROOFWrkD2PjnKG0+Ea0tHI2Pi6Gchnw==", + "dev": true + }, + "node_modules/@cspell/dict-lua": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-lua/-/dict-lua-4.0.3.tgz", + "integrity": "sha512-lDHKjsrrbqPaea13+G9s0rtXjMO06gPXPYRjRYawbNmo4E/e3XFfVzeci3OQDQNDmf2cPOwt9Ef5lu2lDmwfJg==", + "dev": true + }, + "node_modules/@cspell/dict-makefile": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-makefile/-/dict-makefile-1.0.0.tgz", + "integrity": "sha512-3W9tHPcSbJa6s0bcqWo6VisEDTSN5zOtDbnPabF7rbyjRpNo0uHXHRJQF8gAbFzoTzBBhgkTmrfSiuyQm7vBUQ==", + "dev": true + }, + "node_modules/@cspell/dict-monkeyc": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@cspell/dict-monkeyc/-/dict-monkeyc-1.0.6.tgz", + "integrity": "sha512-oO8ZDu/FtZ55aq9Mb67HtaCnsLn59xvhO/t2mLLTHAp667hJFxpp7bCtr2zOrR1NELzFXmKln/2lw/PvxMSvrA==", + "dev": true + }, + "node_modules/@cspell/dict-node": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-node/-/dict-node-4.0.3.tgz", + "integrity": "sha512-sFlUNI5kOogy49KtPg8SMQYirDGIAoKBO3+cDLIwD4MLdsWy1q0upc7pzGht3mrjuyMiPRUV14Bb0rkVLrxOhg==", + "dev": true + }, + "node_modules/@cspell/dict-npm": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/@cspell/dict-npm/-/dict-npm-5.0.15.tgz", + "integrity": "sha512-sX0X5YWNW54F4baW7b5JJB6705OCBIZtUqjOghlJNORS5No7QY1IX1zc5FxNNu4gsaCZITAmfMi4ityXEsEThA==", + "dev": true + }, + "node_modules/@cspell/dict-php": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@cspell/dict-php/-/dict-php-4.0.6.tgz", + "integrity": "sha512-ySAXisf7twoVFZqBV2o/DKiCLIDTHNqfnj0EfH9OoOUR7HL3rb6zJkm0viLUFDO2G/8SyIi6YrN/6KX+Scjjjg==", + "dev": true + }, + "node_modules/@cspell/dict-powershell": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-powershell/-/dict-powershell-5.0.3.tgz", + "integrity": "sha512-lEdzrcyau6mgzu1ie98GjOEegwVHvoaWtzQnm1ie4DyZgMr+N6D0Iyj1lzvtmt0snvsDFa5F2bsYzf3IMKcpcA==", + "dev": true + }, + "node_modules/@cspell/dict-public-licenses": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@cspell/dict-public-licenses/-/dict-public-licenses-2.0.6.tgz", + "integrity": "sha512-bHqpSpJvLCUcWxj1ov/Ki8WjmESpYwRpQlqfdchekOTc93Huhvjm/RXVN1R4fVf4Hspyem1QVkCGqAmjJMj6sw==", + "dev": true + }, + "node_modules/@cspell/dict-python": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@cspell/dict-python/-/dict-python-4.1.11.tgz", + "integrity": "sha512-XG+v3PumfzUW38huSbfT15Vqt3ihNb462ulfXifpQllPok5OWynhszCLCRQjQReV+dgz784ST4ggRxW452/kVg==", "dev": true, "dependencies": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" + "@cspell/dict-data-science": "^1.0.11" } }, - "node_modules/@graphql-modules/core/node_modules/apollo-server-caching": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.5.0.tgz", - "integrity": "sha512-l7ieNCGxUaUAVAAp600HjbUJxVaxjJygtPV0tPTe1Q3HkPy6LEWoY6mNHV7T268g1hxtPTxcdRu7WLsJrg7ufw==", + "node_modules/@cspell/dict-r": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-r/-/dict-r-2.0.1.tgz", + "integrity": "sha512-KCmKaeYMLm2Ip79mlYPc8p+B2uzwBp4KMkzeLd5E6jUlCL93Y5Nvq68wV5fRLDRTf7N1LvofkVFWfDcednFOgA==", + "dev": true + }, + "node_modules/@cspell/dict-ruby": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@cspell/dict-ruby/-/dict-ruby-5.0.2.tgz", + "integrity": "sha512-cIh8KTjpldzFzKGgrqUX4bFyav5lC52hXDKo4LbRuMVncs3zg4hcSf4HtURY+f2AfEZzN6ZKzXafQpThq3dl2g==", + "dev": true + }, + "node_modules/@cspell/dict-rust": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@cspell/dict-rust/-/dict-rust-4.0.2.tgz", + "integrity": "sha512-RhziKDrklzOntxAbY3AvNR58wnFGIo3YS8+dNeLY36GFuWOvXDHFStYw5Pod4f/VXbO/+1tXtywCC4zWfB2p1w==", + "dev": true + }, + "node_modules/@cspell/dict-scala": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-scala/-/dict-scala-5.0.0.tgz", + "integrity": "sha512-ph0twaRoV+ylui022clEO1dZ35QbeEQaKTaV2sPOsdwIokABPIiK09oWwGK9qg7jRGQwVaRPEq0Vp+IG1GpqSQ==", + "dev": true + }, + "node_modules/@cspell/dict-shell": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@cspell/dict-shell/-/dict-shell-1.0.6.tgz", + "integrity": "sha512-hBd9jJsqdxqsN+oweAaA3IqFAdgIAqpuFRExZEbBAlNFAUjhkjux+AJhQAAjq8JcSRAuwWhZzePimg1Sa/mgew==", + "dev": true + }, + "node_modules/@cspell/dict-software-terms": { + "version": "3.3.19", + "resolved": "https://registry.npmjs.org/@cspell/dict-software-terms/-/dict-software-terms-3.3.19.tgz", + "integrity": "sha512-nNQiwhXUe+vEBzOpvi2sVycOLrVJw2bNtwRum1Ya1w74nOKgciCE21UU9fkPGA6p45bU9qmwtPoYccMlHsGMSg==", + "dev": true + }, + "node_modules/@cspell/dict-sql": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-sql/-/dict-sql-2.1.3.tgz", + "integrity": "sha512-SEyTNKJrjqD6PAzZ9WpdSu6P7wgdNtGV2RV8Kpuw1x6bV+YsSptuClYG+JSdRExBTE6LwIe1bTklejUp3ZP8TQ==", + "dev": true + }, + "node_modules/@cspell/dict-svelte": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@cspell/dict-svelte/-/dict-svelte-1.0.2.tgz", + "integrity": "sha512-rPJmnn/GsDs0btNvrRBciOhngKV98yZ9SHmg8qI6HLS8hZKvcXc0LMsf9LLuMK1TmS2+WQFAan6qeqg6bBxL2Q==", + "dev": true + }, + "node_modules/@cspell/dict-swift": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-swift/-/dict-swift-2.0.1.tgz", + "integrity": "sha512-gxrCMUOndOk7xZFmXNtkCEeroZRnS2VbeaIPiymGRHj5H+qfTAzAKxtv7jJbVA3YYvEzWcVE2oKDP4wcbhIERw==", + "dev": true + }, + "node_modules/@cspell/dict-terraform": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-terraform/-/dict-terraform-1.0.0.tgz", + "integrity": "sha512-Ak+vy4HP/bOgzf06BAMC30+ZvL9mzv21xLM2XtfnBLTDJGdxlk/nK0U6QT8VfFLqJ0ZZSpyOxGsUebWDCTr/zQ==", + "dev": true + }, + "node_modules/@cspell/dict-typescript": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@cspell/dict-typescript/-/dict-typescript-3.1.2.tgz", + "integrity": "sha512-lcNOYWjLUvDZdLa0UMNd/LwfVdxhE9rKA+agZBGjL3lTA3uNvH7IUqSJM/IXhJoBpLLMVEOk8v1N9xi+vDuCdA==", + "dev": true + }, + "node_modules/@cspell/dict-vue": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-vue/-/dict-vue-3.0.0.tgz", + "integrity": "sha512-niiEMPWPV9IeRBRzZ0TBZmNnkK3olkOPYxC1Ny2AX4TGlYRajcW0WUtoSHmvvjZNfWLSg2L6ruiBeuPSbjnG6A==", + "dev": true + }, + "node_modules/@cspell/dynamic-import": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/@cspell/dynamic-import/-/dynamic-import-8.3.2.tgz", + "integrity": "sha512-4t0xM5luA3yQhar2xWvYK4wQSDB2r0u8XkpzzJqd57MnJXd7uIAxI0awGUrDXukadRaCo0tDIlMUBemH48SNVg==", "dev": true, "dependencies": { - "lru-cache": "^5.0.0" + "import-meta-resolve": "^4.0.0" }, "engines": { - "node": ">=6" + "node": ">=18.0" } }, - "node_modules/@graphql-modules/core/node_modules/deepmerge": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.0.0.tgz", - "integrity": "sha512-YZ1rOP5+kHor4hMAH+HRQnBQHg+wvS1un1hAOuIcxcBy0hzcUf6Jg2a1w65kpoOUnurOfZbERwjI1TfZxNjcww==", + "node_modules/@cspell/eslint-plugin": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/@cspell/eslint-plugin/-/eslint-plugin-8.3.2.tgz", + "integrity": "sha512-FUUIUMW43KGTddj+SFf3TEgDC5Uv+QvRJqeT8RXdxQL7PLPU7ZQyEGmQZf1DhJCxLzscrVt5YCmA6ZYUjwh/zQ==", "dev": true, + "dependencies": { + "@cspell/cspell-types": "8.3.2", + "cspell-lib": "8.3.2", + "estree-walker": "^3.0.3", + "synckit": "^0.8.8" + }, "engines": { - "node": ">=0.10.0" + "node": ">=18" } }, - "node_modules/@graphql-modules/core/node_modules/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", - "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", + "node_modules/@cspell/strong-weak-map": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/@cspell/strong-weak-map/-/strong-weak-map-8.3.2.tgz", + "integrity": "sha512-Mte/2000ap278kRYOUhiGWI7MNr1+A7WSWJmlcdP4CAH5SO20sZI3/cyZLjJJEyapdhK5vaP1L5J9sUcVDHd3A==", "dev": true, "engines": { - "node": ">=0.8.x" + "node": ">=18" } }, - "node_modules/@graphql-modules/core/node_modules/globby": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz", - "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==", + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, "dependencies": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" + "@jridgewell/trace-mapping": "0.3.9" }, "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/@graphql-modules/core/node_modules/graphql-import": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/graphql-import/-/graphql-import-0.7.1.tgz", - "integrity": "sha512-YpwpaPjRUVlw2SN3OPljpWbVRWAhMAyfSba5U47qGMOSsPLi2gYeJtngGpymjm9nk57RFWEpjqwh4+dpYuFAPw==", - "deprecated": "GraphQL Import has been deprecated and merged into GraphQL Tools, so it will no longer get updates. Use GraphQL Tools instead to stay up-to-date! Check out https://www.graphql-tools.com/docs/migration-from-import for migration and https://the-guild.dev/blog/graphql-tools-v6 for new changes.", + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, "dependencies": { - "lodash": "^4.17.4", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=4.0.0" - }, - "peerDependencies": { - "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0" + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/@graphql-modules/core/node_modules/graphql-import/node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/@graphql-modules/core/node_modules/graphql-toolkit": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/graphql-toolkit/-/graphql-toolkit-0.5.16.tgz", - "integrity": "sha512-J3rAlsO7A/TJTZ7kLcFYy4/sIvB2AxiosxXFQICdsXf8R9b//fy7jmXnNo38ml1mm//915V0U5HMuAvo/hYiWQ==", - "deprecated": "Use @graphql-toolkit/* monorepo packages instead. Check https://github.com/ardatan/graphql-toolkit for more details", + "node_modules/@envelop/core": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@envelop/core/-/core-5.0.0.tgz", + "integrity": "sha512-aJdnH/ptv+cvwfvciCBe7TSvccBwo9g0S5f6u35TBVzRVqIGkK03lFlIL+x1cnfZgN9EfR2b1PH2galrT1CdCQ==", "dev": true, "dependencies": { - "@kamilkisiela/graphql-tools": "4.0.6", - "@types/glob": "7.1.1", - "aggregate-error": "3.0.0", - "asyncro": "^3.0.0", - "cross-fetch": "^3.0.4", - "deepmerge": "4.0.0", - "globby": "10.0.1", - "graphql-import": "0.7.1", - "is-glob": "4.0.1", - "is-valid-path": "0.1.1", - "lodash": "4.17.15", - "tslib": "^1.9.3", - "valid-url": "1.0.9" + "@envelop/types": "5.0.0", + "tslib": "^2.5.0" }, - "peerDependencies": { - "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0", - "graphql-tag-pluck": "^0.8.3" + "engines": { + "node": ">=18.0.0" } }, - "node_modules/@graphql-modules/core/node_modules/tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "node_modules/@graphql-modules/core/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "node_modules/@envelop/types": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@envelop/types/-/types-5.0.0.tgz", + "integrity": "sha512-IPjmgSc4KpQRlO4qbEDnBEixvtb06WDmjKfi/7fkZaryh5HuOmTtixe1EupQI5XfXO8joc3d27uUZ0QdC++euA==", "dev": true, - "bin": { - "uuid": "bin/uuid" + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=18.0.0" } }, - "node_modules/@graphql-modules/di": { - "version": "0.7.17", - "resolved": "https://registry.npmjs.org/@graphql-modules/di/-/di-0.7.17.tgz", - "integrity": "sha512-Lq5sd/3RO+bNb8wVnAg43LWbwrqD57D0AVEqZlqiTwUj1f0mITtQdGMRN7g2sG79U7ngoaQx8VK/IiKh8E1OFQ==", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, "dependencies": { - "events": "3.1.0", - "tslib": "2.0.0" + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "peerDependencies": { - "reflect-metadata": "^0.1.12" + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@graphql-modules/di/node_modules/tslib": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", - "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==", - "dev": true - }, - "node_modules/@hapi/hoek": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.1.1.tgz", - "integrity": "sha512-CAEbWH7OIur6jEOzaai83jq3FmKmv4PmX1JYfs9IrYcGEVI/lyL1EXJGCj7eFVJ0bg5QR8LMxBlEtA+xKiLpFw==", - "dev": true - }, - "node_modules/@hapi/topo": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz", - "integrity": "sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==", + "node_modules/@eslint-community/regexpp": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.0.tgz", + "integrity": "sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==", "dev": true, - "dependencies": { - "@hapi/hoek": "^9.0.0" + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "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" + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.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": ">=8" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "node_modules/@eslint/js": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", + "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", "dev": true, "engines": { - "node": ">=8" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", - "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "node_modules/@graphql-tools/executor": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/executor/-/executor-1.2.0.tgz", + "integrity": "sha512-SKlIcMA71Dha5JnEWlw4XxcaJ+YupuXg0QCZgl2TOLFz4SkGCwU/geAsJvUJFwK2RbVLpQv/UMq67lOaBuwDtg==", "dev": true, + "dependencies": { + "@graphql-tools/utils": "^10.0.0", + "@graphql-typed-document-node/core": "3.2.0", + "@repeaterjs/repeater": "^3.0.4", + "tslib": "^2.4.0", + "value-or-promise": "^1.0.12" + }, "engines": { - "node": ">=8" + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "node_modules/@graphql-tools/merge": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-9.0.1.tgz", + "integrity": "sha512-hIEExWO9fjA6vzsVjJ3s0cCQ+Q/BEeMVJZtMXd7nbaVefVy0YDyYlEkeoYYNV3NVVvu1G9lr6DM1Qd0DGo9Caw==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" + "@graphql-tools/utils": "^10.0.10", + "tslib": "^2.4.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@jest/console/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "node_modules/@graphql-tools/schema": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-10.0.2.tgz", + "integrity": "sha512-TbPsIZnWyDCLhgPGnDjt4hosiNU2mF/rNtSk5BVaXWnZqvKJ6gzJV4fcHcvhRIwtscDMW2/YTnK6dLVnk8pc4w==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@graphql-tools/merge": "^9.0.1", + "@graphql-tools/utils": "^10.0.10", + "tslib": "^2.4.0", + "value-or-promise": "^1.0.12" }, "engines": { - "node": ">=10" + "node": ">=16.0.0" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@jest/core": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", - "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", + "node_modules/@graphql-tools/utils": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.1.2.tgz", + "integrity": "sha512-fX13CYsDnX4yifIyNdiN0cVygz/muvkreWWem6BBw130+ODbRRgfiVveL0NizCEnKXkpvdeTy9Bxvo9LIKlhrw==", "dev": true, "dependencies": { - "@jest/console": "^26.6.2", - "@jest/reporters": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.6.2", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-resolve-dependencies": "^26.6.3", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "jest-watcher": "^26.6.2", - "micromatch": "^4.0.2", - "p-each-series": "^2.1.0", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" + "@graphql-typed-document-node/core": "^3.1.1", + "cross-inspect": "1.0.0", + "dset": "^3.1.2", + "tslib": "^2.4.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@jest/core/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "node_modules/@graphql-typed-document-node/core": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", + "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", + "dev": true, + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-yoga/logger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@graphql-yoga/logger/-/logger-2.0.0.tgz", + "integrity": "sha512-Mg8psdkAp+YTG1OGmvU+xa6xpsAmSir0hhr3yFYPyLNwzUj95DdIwsMpKadDj9xDpYgJcH3Hp/4JMal9DhQimA==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "tslib": "^2.5.2" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=18.0.0" } }, - "node_modules/@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "node_modules/@graphql-yoga/redis-event-target": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@graphql-yoga/redis-event-target/-/redis-event-target-3.0.0.tgz", + "integrity": "sha512-oh5DXd2QLmgD6FazoGMkp1k+l21450sgdPt90Hzjlsz0Us+2gymwlLBlEkiZvHpszrR1463Nw4XMQot/dVwI9Q==", "dev": true, "dependencies": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" + "@graphql-yoga/typed-event-target": "^3.0.0", + "@whatwg-node/events": "^0.1.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=18.0.0" + }, + "peerDependencies": { + "ioredis": "^5.0.6" } }, - "node_modules/@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", - "dev": true, + "node_modules/@graphql-yoga/subscription": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@graphql-yoga/subscription/-/subscription-5.0.0.tgz", + "integrity": "sha512-Ri7sK8hmxd/kwaEa0YT8uqQUb2wOLsmBMxI90QDyf96lzOMJRgBuNYoEkU1pSgsgmW2glceZ96sRYfaXqwVxUw==", "dependencies": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "@graphql-yoga/typed-event-target": "^3.0.0", + "@repeaterjs/repeater": "^3.0.4", + "@whatwg-node/events": "^0.1.0", + "tslib": "^2.5.2" }, "engines": { - "node": ">= 10.14.2" + "node": ">=18.0.0" } }, - "node_modules/@jest/globals": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", - "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", - "dev": true, + "node_modules/@graphql-yoga/typed-event-target": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@graphql-yoga/typed-event-target/-/typed-event-target-3.0.0.tgz", + "integrity": "sha512-w+liuBySifrstuHbFrHoHAEyVnDFVib+073q8AeAJ/qqJfvFvAwUPLLtNohR/WDVRgSasfXtl3dcNuVJWN+rjg==", "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/types": "^26.6.2", - "expect": "^26.6.2" + "@repeaterjs/repeater": "^3.0.4", + "tslib": "^2.5.2" }, "engines": { - "node": ">= 10.14.2" + "node": ">=18.0.0" } }, - "node_modules/@jest/reporters": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", - "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", + "node_modules/@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", + "dev": true + }, + "node_modules/@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", "dev": true, "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^7.0.0" - }, - "engines": { - "node": ">= 10.14.2" - }, - "optionalDependencies": { - "node-notifier": "^8.0.0" + "@hapi/hoek": "^9.0.0" } }, - "node_modules/@jest/reporters/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@humanwhocodes/object-schema": "^2.0.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" }, "engines": { - "node": ">=10" + "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==", + "dev": true, + "engines": { + "node": ">=12.22" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@jest/reporters/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==", + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "dev": true + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.0.tgz", + "integrity": "sha512-naldaJy4hSVhWBgEjfdBY85CAa4UO+W1nx6a1sWStHZ7EUfNiuBTTN2KUYT5dH1+p/xij1t2QSXfCiFJoC5S/Q==", + "cpu": [ + "x64" + ], "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=0.10.0" + "glibc": ">=2.26", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@jest/source-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", - "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.0.tgz", + "integrity": "sha512-FW8iK6rJrg+X2jKD0Ajhjv6y74lToIBEvkZhl42nZt563FfxkCYacrXZtd+q/sRQDypQLzY5WdLkVTbJoPyqNg==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.1.tgz", + "integrity": "sha512-4y8osC0cAc1TRpy02yn5omBeloZZwS62fPZ0WUAYQiLhSFSpWJfY/gMrzKzLcHB9ulUV6ExFiu2elMaixKDbeg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 10.14.2" + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.0" } }, - "node_modules/@jest/source-map/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==", + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.1.tgz", + "integrity": "sha512-LOGKNu5w8uu1evVqUAUKTix2sQu1XDRIYbsi5Q0c/SrXhvJ4QyOx+GaajxmOg5PZSsSnCYPSmhjHHsRBx06/wQ==", + "cpu": [ + "x64" + ], "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=0.10.0" + "musl": ">=1.2.2", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.0" } }, - "node_modules/@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "node_modules/@ioredis/commands": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", + "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==", + "dev": true + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, "dependencies": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=12" } }, - "node_modules/@jest/test-sequencer": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", - "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, - "dependencies": { - "@jest/test-result": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3" + "engines": { + "node": ">=12" }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, "engines": { - "node": ">= 10.14.2" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@jest/transform": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", - "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^26.6.2", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-util": "^26.6.2", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/@jest/transform/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/@jest/transform/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==", + "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": ">=0.10.0" + "node": ">=8" } }, - "node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "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": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" + "sprintf-js": "~1.0.2" } }, - "node_modules/@jest/types/node_modules/chalk": { + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=10" + "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" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@mikro-orm/core": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/@mikro-orm/core/-/core-4.4.4.tgz", - "integrity": "sha512-oCFB9cGdJzgPum4rSB9N5py9fODIe7UPxWGBbEhGZnf4bcHrGpsO44WS3aSycypnQ3Lb8oqbge++pAIWQi7JlA==", + "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": { - "ansi-colors": "4.1.1", - "clone": "2.1.2", - "escaya": "0.0.61", - "fs-extra": "9.1.0", - "globby": "11.0.2", - "reflect-metadata": "0.1.13", - "strip-json-comments": "3.1.1" + "p-locate": "^4.1.0" }, "engines": { - "node": ">= 10.13.0" - }, - "peerDependencies": { - "@mikro-orm/entity-generator": "^4.0.0", - "@mikro-orm/mariadb": "^4.0.0", - "@mikro-orm/migrations": "^4.0.0", - "@mikro-orm/mongodb": "^4.0.0", - "@mikro-orm/mysql": "^4.0.0", - "@mikro-orm/postgresql": "^4.0.0", - "@mikro-orm/sqlite": "^4.0.0" - }, - "peerDependenciesMeta": { - "@mikro-orm/entity-generator": { - "optional": true - }, - "@mikro-orm/mariadb": { - "optional": true - }, - "@mikro-orm/migrations": { - "optional": true - }, - "@mikro-orm/mongodb": { - "optional": true - }, - "@mikro-orm/mysql": { - "optional": true - }, - "@mikro-orm/postgresql": { - "optional": true - }, - "@mikro-orm/sqlite": { - "optional": true - } + "node": ">=8" } }, - "node_modules/@mikro-orm/knex": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/@mikro-orm/knex/-/knex-4.4.4.tgz", - "integrity": "sha512-dJVL1aURd17qmWsodJgyf9EQ2dyNwV4feAQzAgtwDD+OYapGaMfzKFMn5fomcQpE/IclMPwBxx07l43L275jtg==", + "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": { - "fs-extra": "9.1.0", - "knex": "0.21.17", - "sqlstring": "2.3.2" + "p-try": "^2.0.0" }, "engines": { - "node": ">= 10.13.0" - }, - "peerDependencies": { - "@mikro-orm/core": "^4.0.0", - "mssql": "^6.2.0", - "mysql": "^2.18.1", - "mysql2": "^2.1.0", - "pg": "^8.0.3", - "sqlite3": "^5.0.0" + "node": ">=6" }, - "peerDependenciesMeta": { - "mssql": { - "optional": true - }, - "mysql": { - "optional": true - }, - "mysql2": { - "optional": true - }, - "pg": { - "optional": true - }, - "sqlite3": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@mikro-orm/postgresql": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/@mikro-orm/postgresql/-/postgresql-4.4.4.tgz", - "integrity": "sha512-o30y5yopqmgyJltRLKoRi1xz/p67Mu1PvQkV2v10Lk/MhfxvxUQWi7Vn10zOucwKMM57ZjFY/dZUNwEzxoYNHw==", + "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": { - "@mikro-orm/knex": "^4.4.4", - "pg": "8.5.1" + "p-limit": "^2.2.0" }, "engines": { - "node": ">= 10.13.0" - }, - "peerDependencies": { - "@mikro-orm/core": "^4.0.0" + "node": ">=8" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", - "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.4", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } + "node_modules/@istanbuljs/load-nyc-config/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/@nodelib/fs.stat": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", - "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", + "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": ">=8" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", - "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", "dev": true, "dependencies": { - "@nodelib/fs.scandir": "2.1.4", - "fastq": "^1.6.0" + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" }, "engines": { - "node": ">= 8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@npmcli/move-file": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.0.1.tgz", - "integrity": "sha512-Uv6h1sT+0DrblvIrolFtbvM1FgWm+/sy4B3pvLp67Zys+thcukzS5ekn7HsZFGpWP4Q3fYJCljbWQE/XivMRLw==", + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", "dev": true, "dependencies": { - "mkdirp": "^1.0.4" + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=10" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=", - "dev": true - }, - "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==", - "dev": true - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "dev": true - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=", - "dev": true - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", "dev": true, "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=", - "dev": true - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=", - "dev": true - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=", - "dev": true - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=", - "dev": true - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", - "dev": true - }, - "node_modules/@sideway/address": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.1.tgz", - "integrity": "sha512-+I5aaQr3m0OAmMr7RQ3fR9zx55sejEYR2BFJaxL+zT3VM2611X0SHvPWIbAUBZVTn/YzYKbV8gJ2oT/QELknfQ==", + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", "dev": true, "dependencies": { - "@hapi/hoek": "^9.0.0" + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@sideway/formula": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz", - "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==", - "dev": true - }, - "node_modules/@sideway/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", - "dev": true - }, - "node_modules/@sinonjs/commons": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", - "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", "dev": true, "dependencies": { - "type-detect": "4.0.8" + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@sinonjs/fake-timers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", - "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", "dev": true, "dependencies": { - "@sinonjs/commons": "^1.7.0" + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@sqltools/formatter": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.2.tgz", - "integrity": "sha512-/5O7Fq6Vnv8L6ucmPjaWbVG1XkP4FO+w5glqfkIsq3Xw4oyNAdJddbnYodNDAfjVUvo/rrSCTom4kAND7T1o5Q==", - "dev": true - }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, "engines": { - "node": ">= 6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@typegoose/typegoose": { - "version": "7.4.8", - "resolved": "https://registry.npmjs.org/@typegoose/typegoose/-/typegoose-7.4.8.tgz", - "integrity": "sha512-fMd+RfyX9e9cCt2P5arh4q3hJtd/emHkjiES0VEIgtOH/XRF7av7ZuktRIEn/KO51H5MSEo9H+Xok6oK+nT7zw==", + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", "dev": true, - "license": "MIT", "dependencies": { - "lodash": "^4.17.20", - "loglevel": "^1.7.0", - "reflect-metadata": "^0.1.13", - "semver": "^7.3.2", - "tslib": "^2.0.1" + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" }, "engines": { - "node": ">=10.15.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { - "@types/mongoose": "^5.10.2", - "mongoose": "5.10.0 - 5.10.18" + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/@typegoose/typegoose/node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/@types/accepts": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz", - "integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==", + "node_modules/@jest/reporters/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "dependencies": { - "@types/node": "*" + "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/@types/babel__core": { - "version": "7.1.12", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.12.tgz", - "integrity": "sha512-wMTHiiTiBAAPebqaPiPDLFA4LYPKr6Ph0Xq/6rq1Ur3v66HXyG+clfR9CNETkD7MQS8ZHvpQOtA53DLws5WAEQ==", + "node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz", + "integrity": "sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==", "dev": true, "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" } }, - "node_modules/@types/babel__generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", - "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, "dependencies": { - "@babel/types": "^7.0.0" + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@types/babel__template": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz", - "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==", + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", "dev": true, "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@types/babel__traverse": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.11.0.tgz", - "integrity": "sha512-kSjgDMZONiIfSH1Nxcr5JIRMwUetDki63FSQfpTCz8ogF3Ulqm8+mr5f78dUYs6vMiB6gBusQqfQmBvHZj/lwg==", + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", "dev": true, "dependencies": { - "@babel/types": "^7.3.0" + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@types/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", "dev": true, "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/bson": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.3.tgz", - "integrity": "sha512-mVRvYnTOZJz3ccpxhr3wgxVmSeiYinW+zlzQz3SXWaJmD1DuL05Jeq7nKw3SnbKmbleW5qrLG5vdyWe/A9sXhw==", - "dev": true, - "dependencies": { - "@types/node": "*" + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@types/connect": { - "version": "3.4.34", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", - "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", "dev": true, "dependencies": { - "@types/node": "*" + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@types/content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-P1bffQfhD3O4LW0ioENXUhZ9OIa0Zn+P7M+pWgkCKaT53wVLSq0mrKksCID/FGHpFhRSxRGhgrQmfhRuzwtKdg==", + "node_modules/@jest/transform/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/@types/cookies": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.6.tgz", - "integrity": "sha512-FK4U5Qyn7/Sc5ih233OuHO0qAkOpEcD/eG6584yEiLKizTFRny86qHLe/rej3HFQrkBuUjF4whFliAdODbVN/w==", + "node_modules/@jest/transform/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": { - "@types/connect": "*", - "@types/express": "*", - "@types/keygrip": "*", - "@types/node": "*" + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/@types/cors": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.8.tgz", - "integrity": "sha512-fO3gf3DxU2Trcbr75O7obVndW/X5k8rJNZkLXlQWStTHhP71PkRqjwPIEI0yMnJdg9R9OasjU+Bsr+Hr1xy/0w==", + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "dev": true, "dependencies": { - "@types/express": "*" + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "node_modules/@types/expect": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz", - "integrity": "sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==", + "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==", "dev": true }, - "node_modules/@types/express": { - "version": "4.17.7", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.7.tgz", - "integrity": "sha512-dCOT5lcmV/uC2J9k0rPafATeeyz+99xTt54ReX11/LObZgfzJqZNcW27zGhYyX+9iSEGXGt5qLPwRSvBZcLvtQ==", + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "*", - "@types/qs": "*", - "@types/serve-static": "*" + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" } }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.18", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.18.tgz", - "integrity": "sha512-m4JTwx5RUBNZvky/JJ8swEJPKFd8si08pPF2PfizYjGZOKr/svUWPcoUmLow6MmPzhasphB7gSTINY67xn3JNA==", + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "dev": true, - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" + "engines": { + "node": ">=6.0.0" } }, - "node_modules/@types/fs-capacitor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/fs-capacitor/-/fs-capacitor-2.0.0.tgz", - "integrity": "sha512-FKVPOCFbhCvZxpVAMhdBdTfVfXUpsh15wFHgqOKxh9N9vzWZVuWCSijZ5T4U34XYNnuj2oduh6xcs1i+LPI+BQ==", + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "dev": true, - "dependencies": { - "@types/node": "*" + "engines": { + "node": ">=6.0.0" } }, - "node_modules/@types/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true }, - "node_modules/@types/glob-stream": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/glob-stream/-/glob-stream-6.1.0.tgz", - "integrity": "sha512-RHv6ZQjcTncXo3thYZrsbAVwoy4vSKosSWhuhuQxLOTv74OJuFQxXkmUuZCr3q9uNBEVCvIzmZL/FeRNbHZGUg==", + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", + "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", "dev": true, "dependencies": { - "@types/glob": "*", - "@types/node": "*" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@types/graceful-fs": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.4.tgz", - "integrity": "sha512-mWA/4zFQhfvOA8zWkXobwJvBD7vzcxgrOQ0J5CH1votGqdq9m7+FwtGaqyCZqC3NyyBkc9z4m+iry4LlqcMWJg==", + "node_modules/@microsoft/tsdoc": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz", + "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==", + "dev": true + }, + "node_modules/@microsoft/tsdoc-config": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.16.2.tgz", + "integrity": "sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==", "dev": true, "dependencies": { - "@types/node": "*" + "@microsoft/tsdoc": "0.14.2", + "ajv": "~6.12.6", + "jju": "~1.4.0", + "resolve": "~1.19.0" } }, - "node_modules/@types/gulp": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@types/gulp/-/gulp-4.0.8.tgz", - "integrity": "sha512-RIhiptRwikdFMICikX+Kn8duKR4R7yO2CKMhkcIfvUwZ3UJSjHlvhHDJ2DsurJWETePqdjteO9MLRtObuCt7Sw==", + "node_modules/@microsoft/tsdoc-config/node_modules/resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", "dev": true, "dependencies": { - "@types/undertaker": "*", - "@types/vinyl-fs": "*", - "chokidar": "^3.3.1" + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/gulp-replace": { - "version": "0.0.31", - "resolved": "https://registry.npmjs.org/@types/gulp-replace/-/gulp-replace-0.0.31.tgz", - "integrity": "sha512-dbgQ1u0N9ShXrzahBgQfMSu6qUh8nlTLt7whhQ0S0sEUHhV3scysppJ1UX0fl53PJENgAL99ueykddyrCaDt7g==", + "node_modules/@mikro-orm/core": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@mikro-orm/core/-/core-6.0.2.tgz", + "integrity": "sha512-jmHpG/H6++FzsVMHNMNJlRLJBtppaWfNaKhBrV5kbx/ltSgt/DrLswPG2tx7Dhia6MFh49k12sgJeacGz9bGqw==", "dev": true, "dependencies": { - "@types/node": "*" + "dataloader": "2.2.2", + "dotenv": "16.3.1", + "esprima": "4.0.1", + "fs-extra": "11.2.0", + "globby": "11.1.0", + "mikro-orm": "6.0.2", + "reflect-metadata": "0.2.1" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "url": "https://github.com/sponsors/b4nan" } }, - "node_modules/@types/http-assert": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.1.tgz", - "integrity": "sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ==", - "dev": true - }, - "node_modules/@types/http-errors": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-1.8.0.tgz", - "integrity": "sha512-2aoSC4UUbHDj2uCsCxcG/vRMXey/m17bC7UwitVm5hn22nI8O8Y9iDpA76Orc+DWkQ4zZrOKEshCqR/jSuXAHA==", - "dev": true - }, - "node_modules/@types/ioredis": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@types/ioredis/-/ioredis-4.22.0.tgz", - "integrity": "sha512-BhgyAqt+CIFj/ejdYpWSGYUQzoQr7sFOBYLL8yEExa1tSTi2cy2D3a952zF8Tm4Q1cY3srn8xXZfb2riX6hWjw==", + "node_modules/@mikro-orm/core/node_modules/dotenv": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", "dev": true, - "dependencies": { - "@types/node": "*" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" } }, - "node_modules/@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==", + "node_modules/@mikro-orm/core/node_modules/reflect-metadata": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.1.tgz", + "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==", "dev": true }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "node_modules/@mikro-orm/knex": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@mikro-orm/knex/-/knex-6.2.1.tgz", + "integrity": "sha512-PZwCof0bCRcc8n90IyLgvpz4Pk+fva4RFo1kxaU+48M+QBDYtXpWU36mz32lcPP4fpt0fgLjEz0iLaSqaNy5pA==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "*" + "fs-extra": "11.2.0", + "knex": "3.1.0", + "sqlstring": "2.3.3" + }, + "engines": { + "node": ">= 18.12.0" + }, + "peerDependencies": { + "@mikro-orm/core": "^6.0.0" } }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "node_modules/@mikro-orm/postgresql": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@mikro-orm/postgresql/-/postgresql-6.2.1.tgz", + "integrity": "sha512-W/Gen9B8kUa7FdPg1jO1b6Ks1usegg6YEKg3RUgLdNB7e6CKm8VfkZdZoxaWeoIF2TZn9px6vF3tZMwJ9NOvVA==", "dev": true, "dependencies": { - "@types/istanbul-lib-report": "*" + "@mikro-orm/knex": "6.2.1", + "pg": "8.11.5", + "postgres-array": "3.0.2", + "postgres-date": "2.1.0", + "postgres-interval": "4.0.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "peerDependencies": { + "@mikro-orm/core": "^6.0.0" } }, - "node_modules/@types/jest": { - "version": "26.0.20", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.20.tgz", - "integrity": "sha512-9zi2Y+5USJRxd0FsahERhBwlcvFh6D2GLQnY2FH2BzK8J9s9omvNHIbvABwIluXa0fD8XVKMLTO0aOEuUfACAA==", + "node_modules/@mikro-orm/postgresql/node_modules/postgres-array": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.2.tgz", + "integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==", "dev": true, - "dependencies": { - "jest-diff": "^26.0.0", - "pretty-format": "^26.0.0" + "engines": { + "node": ">=12" } }, - "node_modules/@types/keygrip": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.2.tgz", - "integrity": "sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==", - "dev": true + "node_modules/@mikro-orm/postgresql/node_modules/postgres-date": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-2.1.0.tgz", + "integrity": "sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==", + "dev": true, + "engines": { + "node": ">=12" + } }, - "node_modules/@types/koa": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.13.0.tgz", - "integrity": "sha512-hNs1Z2lX+R5sZroIy/WIGbPlH/719s/Nd5uIjSIAdHn9q+g7z6mxOnhwMjK1urE4/NUP0SOoYUOD4MnvD9FRNw==", + "node_modules/@mikro-orm/postgresql/node_modules/postgres-interval": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-4.0.2.tgz", + "integrity": "sha512-EMsphSQ1YkQqKZL2cuG0zHkmjCCzQqQ71l2GXITqRwjhRleCdv00bDk/ktaSi0LnlaPzAc3535KTrjXsTdtx7A==", "dev": true, - "dependencies": { - "@types/accepts": "*", - "@types/content-disposition": "*", - "@types/cookies": "*", - "@types/http-assert": "*", - "@types/http-errors": "*", - "@types/keygrip": "*", - "@types/koa-compose": "*", - "@types/node": "*" + "engines": { + "node": ">=12" } }, - "node_modules/@types/koa-compose": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.5.tgz", - "integrity": "sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==", + "node_modules/@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==", "dev": true, "dependencies": { - "@types/koa": "*" + "sparse-bitfield": "^3.0.3" } }, - "node_modules/@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==", - "dev": true + "node_modules/@nicolo-ribaudo/semver-v6": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz", + "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } }, - "node_modules/@types/merge2": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@types/merge2/-/merge2-1.3.0.tgz", - "integrity": "sha512-3xFWjsGhm5GCVlRrcrrVr9oapPxpbG5M3G/4JGF+Gra++7DWoeDOQphCEhyMpbpbptD3w/4PesYIMby/yHrzkQ==", + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "dependencies": { - "@types/node": "*" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", - "dev": true - }, - "node_modules/@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } }, - "node_modules/@types/mongodb": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.3.tgz", - "integrity": "sha512-6YNqGP1hk5bjUFaim+QoFFuI61WjHiHE1BNeB41TA00Xd2K7zG4lcWyLLq/XtIp36uMavvS5hoAUJ+1u/GcX2Q==", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "dependencies": { - "@types/bson": "*", - "@types/node": "*" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/@types/mongoose": { - "version": "5.10.3", - "resolved": "https://registry.npmjs.org/@types/mongoose/-/mongoose-5.10.3.tgz", - "integrity": "sha512-VfdnaFImXEJZZiuL2ID/ysZs4inOIjxwrAnUgkr5eum2O2BLhFkiSI0i87AwignVva1qWTJ3H3DyM0Rf4USJ4A==", + "node_modules/@npmcli/fs": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.0.tgz", + "integrity": "sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==", "dev": true, "dependencies": { - "@types/mongodb": "*", - "@types/node": "*" + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@types/node": { - "version": "14.14.31", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.31.tgz", - "integrity": "sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==" + "node_modules/@opentelemetry/api": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.4.1.tgz", + "integrity": "sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } }, - "node_modules/@types/node-fetch": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.4.tgz", - "integrity": "sha512-Oz6id++2qAOFuOlE1j0ouk1dzl3mmI1+qINPNBhi9nt/gVOz0G+13Ao6qjhdF0Ys+eOkhu6JnFmt38bR3H0POQ==", + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "dev": true, - "dependencies": { - "@types/node": "*" + "optional": true, + "engines": { + "node": ">=14" } }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", - "dev": true + "node_modules/@pkgr/core": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.0.tgz", + "integrity": "sha512-Zwq5OCzuwJC2jwqmpEQt7Ds1DTi6BWSwoGkbb1n9pO3hzb35BoJELx7c0T23iDkBGkh2e7tvOtjF3tr3OaQHDQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } }, - "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==", + "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==", "dev": true }, - "node_modules/@types/prettier": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.1.6.tgz", - "integrity": "sha512-6gOkRe7OIioWAXfnO/2lFiv+SJichKVSys1mSsgyrYHSEjk8Ctv4tSR/Odvnu+HWlH2C8j53dahU03XmQdd5fA==", + "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==", "dev": true }, - "node_modules/@types/qs": { - "version": "6.9.5", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.5.tgz", - "integrity": "sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ==", + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", "dev": true }, - "node_modules/@types/range-parser": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", - "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", "dev": true }, - "node_modules/@types/rimraf": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-3.0.0.tgz", - "integrity": "sha512-7WhJ0MdpFgYQPXlF4Dx+DhgvlPCfz/x5mHaeDQAKhcenvQP1KCpLQ18JklAqeGMYSAT2PxLpzd0g2/HE7fj7hQ==", + "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==", "dev": true, "dependencies": { - "@types/glob": "*", - "@types/node": "*" + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" } }, - "node_modules/@types/semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-+nVsLKlcUCeMzD2ufHEYuJ9a2ovstb6Dp52A5VsoKxDXgvE051XgHI/33I1EymwkRGQkwnA0LkhnUzituGs4EQ==" - }, - "node_modules/@types/serve-static": { - "version": "1.13.9", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz", - "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==", - "dev": true, - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } + "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==", + "dev": true }, - "node_modules/@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "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==", "dev": true }, - "node_modules/@types/undertaker": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@types/undertaker/-/undertaker-1.2.6.tgz", - "integrity": "sha512-sG5MRcsWRokQXtj94uCqPxReXldm4ZvXif34YthgHEpzipcBAFTg+4IoWFcvdA0hGM1KdpPj2efdzcD2pETqQA==", - "dev": true, - "dependencies": { - "@types/node": "*", - "@types/undertaker-registry": "*", - "async-done": "~1.3.2" - } + "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==", + "dev": true }, - "node_modules/@types/undertaker-registry": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/undertaker-registry/-/undertaker-registry-1.0.1.tgz", - "integrity": "sha512-Z4TYuEKn9+RbNVk1Ll2SS4x1JeLHecolIbM/a8gveaHsW0Hr+RQMraZACwTO2VD7JvepgA6UO1A1VrbktQrIbQ==", + "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==", "dev": true }, - "node_modules/@types/validator": { - "version": "13.1.3", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.1.3.tgz", - "integrity": "sha512-DaOWN1zf7j+8nHhqXhIgNmS+ltAC53NXqGxYuBhWqWgqolRhddKzfZU814lkHQSTG0IUfQxU7Cg0gb8fFWo2mA==", + "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==", "dev": true }, - "node_modules/@types/vinyl": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.4.tgz", - "integrity": "sha512-2o6a2ixaVI2EbwBPg1QYLGQoHK56p/8X/sGfKbFC8N6sY9lfjsMf/GprtkQkSya0D4uRiutRZ2BWj7k3JvLsAQ==", - "dev": true, - "dependencies": { - "@types/expect": "^1.20.4", - "@types/node": "*" - } + "node_modules/@repeaterjs/repeater": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@repeaterjs/repeater/-/repeater-3.0.4.tgz", + "integrity": "sha512-AW8PKd6iX3vAZ0vA43nOUOnbq/X5ihgU+mSXXqunMkeQADGiqw/PY0JNeYtD5sr0PAy51YPgAPbDoeapv9r8WA==" }, - "node_modules/@types/vinyl-fs": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/@types/vinyl-fs/-/vinyl-fs-2.4.11.tgz", - "integrity": "sha512-2OzQSfIr9CqqWMGqmcERE6Hnd2KY3eBVtFaulVo3sJghplUcaeMdL9ZjEiljcQQeHjheWY9RlNmumjIAvsBNaA==", + "node_modules/@sideway/address": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", + "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", "dev": true, "dependencies": { - "@types/glob-stream": "*", - "@types/node": "*", - "@types/vinyl": "*" + "@hapi/hoek": "^9.0.0" } }, - "node_modules/@types/ws": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.0.tgz", - "integrity": "sha512-Y29uQ3Uy+58bZrFLhX36hcI3Np37nqWE7ky5tjiDoy1GDZnIwVxS0CgF+s+1bXMzjKBFy+fqaRfb708iNzdinw==", + "node_modules/@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", + "dev": true + }, + "node_modules/@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", + "dev": true + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", "dev": true, "dependencies": { - "@types/node": "*" + "type-detect": "4.0.8" } }, - "node_modules/@types/yargs": { - "version": "15.0.12", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.12.tgz", - "integrity": "sha512-f+fD/fQAo3BCbCDlrUpznF1A5Zp9rB0noS5vnoormHSIPFKL0Z2DcUJ3Gxp5ytH4uLRNxy7AwYUC9exZzqGMAw==", + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, "dependencies": { - "@types/yargs-parser": "*" + "@sinonjs/commons": "^3.0.0" } }, - "node_modules/@types/yargs-parser": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", - "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==", + "node_modules/@sqltools/formatter": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.5.tgz", + "integrity": "sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==", "dev": true }, - "node_modules/@wry/equality": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.1.11.tgz", - "integrity": "sha512-mwEVBDUVODlsQQ5dfuLUS5/Tf7jqUKyhKYHmVi4fPB6bDMOfWvUPJmKgS1Z7Za/sOI3vzWt4+O7yCiL/70MogA==", + "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==", "dev": true, - "dependencies": { - "tslib": "^1.9.3" + "engines": { + "node": ">= 10" } }, - "node_modules/@wry/equality/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", "dev": true }, - "node_modules/abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", "dev": true }, - "node_modules/accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "node_modules/@typegoose/typegoose": { + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/@typegoose/typegoose/-/typegoose-12.2.0.tgz", + "integrity": "sha512-6gC5aIfccXw4IZOMe3oSef63M6leDyMvuycfwzQdVi8M9C5UnpaV8tO1xzmxiOxUHDST0GdDW/aWCCX6MtOQxg==", "dev": true, "dependencies": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" + "lodash": "^4.17.20", + "loglevel": "^1.9.1", + "reflect-metadata": "^0.2.1", + "semver": "^7.6.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" + "node": ">=16.20.1" }, - "engines": { - "node": ">=0.4.0" + "peerDependencies": { + "mongoose": "~8.2.0" } }, - "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "node_modules/@typegoose/typegoose/node_modules/reflect-metadata": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.1.tgz", + "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==", + "dev": true + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" } }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", "dev": true, - "engines": { - "node": ">=0.4.0" + "dependencies": { + "@babel/types": "^7.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==", + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" } }, - "node_modules/agent-base/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "node_modules/@types/babel__traverse": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", + "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", "dev": true, "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "@babel/types": "^7.20.7" } }, - "node_modules/agent-base/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/agentkeepalive": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.1.3.tgz", - "integrity": "sha512-wn8fw19xKZwdGPO47jivonaHRTd+nGOMP1z11sgGeQzDy2xd5FG0R67dIMcKHDE2cJ5y+YXV30XVGUBPRSY7Hg==", + "node_modules/@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", "dev": true, "dependencies": { - "debug": "^4.1.0", - "depd": "^1.1.2", - "humanize-ms": "^1.2.1" - }, - "engines": { - "node": ">= 8.0.0" + "@types/connect": "*", + "@types/node": "*" } }, - "node_modules/agentkeepalive/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", "dev": true, "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "@types/node": "*" } }, - "node_modules/agentkeepalive/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "node_modules/@types/estree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", "dev": true }, - "node_modules/aggregate-error": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.0.tgz", - "integrity": "sha512-yKD9kEoJIR+2IFqhMwayIBgheLYbB3PS2OBhWae1L/ODTd/JF/30cW0bc9TqzRL3k4U41Dieu3BF4I29p8xesA==", + "node_modules/@types/express": { + "version": "4.17.17", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", + "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", "dev": true, "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^3.2.0" - }, - "engines": { - "node": ">=8" + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" } }, - "node_modules/aggregate-error/node_modules/indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "node_modules/@types/express-serve-static-core": { + "version": "4.17.35", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz", + "integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==", "dev": true, - "engines": { - "node": ">=4" + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "@types/minimatch": "*", + "@types/node": "*" } }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", "dev": true, - "engines": { - "node": ">=6" + "dependencies": { + "@types/node": "*" } }, - "node_modules/ansi-escapes": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", - "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "node_modules/@types/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==", + "dev": true + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "node_modules/@types/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, "dependencies": { - "type-fest": "^0.11.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "@types/istanbul-lib-coverage": "*" } }, - "node_modules/ansi-gray": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", - "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { - "ansi-wrap": "0.1.0" - }, - "engines": { - "node": ">=0.10.0" + "@types/istanbul-lib-report": "*" } }, - "node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "node_modules/@types/jest": { + "version": "29.5.11", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.11.tgz", + "integrity": "sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@types/json-schema": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", + "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", + "dev": true + }, + "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/lodash": { + "version": "4.14.195", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz", + "integrity": "sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg==", + "dev": true + }, + "node_modules/@types/lodash.merge": { + "version": "4.6.9", + "resolved": "https://registry.npmjs.org/@types/lodash.merge/-/lodash.merge-4.6.9.tgz", + "integrity": "sha512-23sHDPmzd59kUgWyKGiOMO2Qb9YtqRO/x4IhkgNUiPQ1+5MUVqi6bCZeq9nBJ17msjIMbEIO5u+XW4Kz6aGUhQ==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "@types/lodash": "*" } }, - "node_modules/ansi-wrap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "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==", + "dev": true }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", + "node_modules/@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", "dev": true }, - "node_modules/anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "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==", "dev": true, "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" + "undici-types": "~5.26.4" } }, - "node_modules/apollo-cache-control": { - "version": "0.11.6", - "resolved": "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.11.6.tgz", - "integrity": "sha512-YZ+uuIG+fPy+mkpBS2qKF0v1qlzZ3PW6xZVaDukeK3ed3iAs4L/2YnkTqau3OmoF/VPzX2FmSkocX/OVd59YSw==", + "node_modules/@types/node-fetch": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.4.tgz", + "integrity": "sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==", "dev": true, "dependencies": { - "apollo-server-env": "^3.0.0", - "apollo-server-plugin-base": "^0.10.4" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependencies": { - "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" - } + "@types/node": "*", + "form-data": "^3.0.0" + } + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "node_modules/@types/semver": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", + "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==" }, - "node_modules/apollo-datasource": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-0.7.3.tgz", - "integrity": "sha512-PE0ucdZYjHjUyXrFWRwT02yLcx2DACsZ0jm1Mp/0m/I9nZu/fEkvJxfsryXB6JndpmQO77gQHixf/xGCN976kA==", + "node_modules/@types/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", + "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==", "dev": true, "dependencies": { - "apollo-server-caching": "^0.5.3", - "apollo-server-env": "^3.0.0" - }, - "engines": { - "node": ">=6" + "@types/mime": "^1", + "@types/node": "*" } }, - "node_modules/apollo-env": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/apollo-env/-/apollo-env-0.6.6.tgz", - "integrity": "sha512-hXI9PjJtzmD34XviBU+4sPMOxnifYrHVmxpjykqI/dUD2G3yTiuRaiQqwRwB2RCdwC1Ug/jBfoQ/NHDTnnjndQ==", + "node_modules/@types/serve-static": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz", + "integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==", "dev": true, "dependencies": { - "@types/node-fetch": "2.5.7", - "core-js": "^3.0.1", - "node-fetch": "^2.2.0", - "sha.js": "^2.4.11" - }, - "engines": { - "node": ">=8" + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/shelljs": { + "version": "0.8.15", + "resolved": "https://registry.npmjs.org/@types/shelljs/-/shelljs-0.8.15.tgz", + "integrity": "sha512-vzmnCHl6hViPu9GNLQJ+DZFd6BQI2DBTUeOvYHqkWQLMfKAAQYMb/xAmZkTogZI/vqXHCWkqDRymDI5p0QTi5Q==", + "dev": true, + "dependencies": { + "@types/glob": "~7.2.0", + "@types/node": "*" } }, - "node_modules/apollo-env/node_modules/@types/node-fetch": { - "version": "2.5.7", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.7.tgz", - "integrity": "sha512-o2WVNf5UhWRkxlf6eq+jMZDu7kjgpgJfl4xVNlvryc95O/6F2ld8ztKX+qu+Rjyet93WAWm5LjeX9H5FGkODvw==", + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "node_modules/@types/uuid": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.7.tgz", + "integrity": "sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g==", + "dev": true + }, + "node_modules/@types/validator": { + "version": "13.7.17", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.17.tgz", + "integrity": "sha512-aqayTNmeWrZcvnG2MG9eGYI6b7S5fl+yKgPs6bAjOTwPS316R5SxBGKvtSExfyoJU7pIeHJfsHI0Ji41RVMkvQ==", + "dev": 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==", + "dev": true + }, + "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==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@types/node": "*", - "form-data": "^3.0.0" + "@types/webidl-conversions": "*" } }, - "node_modules/apollo-graphql": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/apollo-graphql/-/apollo-graphql-0.6.0.tgz", - "integrity": "sha512-BxTf5LOQe649e9BNTPdyCGItVv4Ll8wZ2BKnmiYpRAocYEXAVrQPWuSr3dO4iipqAU8X0gvle/Xu9mSqg5b7Qg==", + "node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", "dev": true, "dependencies": { - "apollo-env": "^0.6.5", - "lodash.sortby": "^4.7.0" + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.18.1.tgz", + "integrity": "sha512-nISDRYnnIpk7VCFrGcu1rnZfM1Dh9LRHnfgdkjcbi/l7g16VYRri3TjXi9Ir4lOZSw5N/gnV/3H7jIPQ8Q4daA==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.18.1", + "@typescript-eslint/type-utils": "6.18.1", + "@typescript-eslint/utils": "6.18.1", + "@typescript-eslint/visitor-keys": "6.18.1", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": ">=6" + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "graphql": "^14.2.1 || ^15.0.0" + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/apollo-link": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.14.tgz", - "integrity": "sha512-p67CMEFP7kOG1JZ0ZkYZwRDa369w5PIjtMjvrQd/HnIV8FRsHRqLqK+oAZQnFa1DDdZtOtHTi+aMIW6EatC2jg==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.18.1.tgz", + "integrity": "sha512-BgdBwXPFmZzaZUuw6wKiHKIovms97a7eTImjkXCZE04TGHysG+0hDQPmygyvgtkoB/aOQwSM/nWv3LzrOIQOBw==", "dev": true, "dependencies": { - "apollo-utilities": "^1.3.0", - "ts-invariant": "^0.4.0", - "tslib": "^1.9.3", - "zen-observable-ts": "^0.8.21" + "@typescript-eslint/types": "6.18.1", + "@typescript-eslint/visitor-keys": "6.18.1" }, - "peerDependencies": { - "graphql": "^0.11.3 || ^0.12.3 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/apollo-link/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.18.1.tgz", + "integrity": "sha512-4TuMAe+tc5oA7wwfqMtB0Y5OrREPF1GeJBAjqwgZh1lEMH5PJQgWgHGfYufVB51LtjD+peZylmeyxUXPfENLCw==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } }, - "node_modules/apollo-reporting-protobuf": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-0.6.2.tgz", - "integrity": "sha512-WJTJxLM+MRHNUxt1RTl4zD0HrLdH44F2mDzMweBj1yHL0kSt8I1WwoiF/wiGVSpnG48LZrBegCaOJeuVbJTbtw==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.18.1.tgz", + "integrity": "sha512-fv9B94UAhywPRhUeeV/v+3SBDvcPiLxRZJw/xZeeGgRLQZ6rLMG+8krrJUyIf6s1ecWTzlsbp0rlw7n9sjufHA==", "dev": true, "dependencies": { - "@apollo/protobufjs": "^1.0.3" + "@typescript-eslint/types": "6.18.1", + "@typescript-eslint/visitor-keys": "6.18.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/apollo-server": { - "version": "2.21.0", - "resolved": "https://registry.npmjs.org/apollo-server/-/apollo-server-2.21.0.tgz", - "integrity": "sha512-OqngjOSB0MEH6VKGWHcrqt4y39HlhYh9CrMvn4PhadTt53IPYRmBglk5qSRA8xMorGqy60iKrOReqj5YfCjTOg==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.18.1.tgz", + "integrity": "sha512-zZmTuVZvD1wpoceHvoQpOiewmWu3uP9FuTWo8vqpy2ffsmfCE8mklRPi+vmnIYAIk9t/4kOThri2QCDgor+OpQ==", "dev": true, "dependencies": { - "apollo-server-core": "^2.21.0", - "apollo-server-express": "^2.21.0", - "express": "^4.0.0", - "graphql-subscriptions": "^1.0.0", - "graphql-tools": "^4.0.8", - "stoppable": "^1.1.0" + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.18.1", + "@typescript-eslint/types": "6.18.1", + "@typescript-eslint/typescript-estree": "6.18.1", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "eslint": "^7.0.0 || ^8.0.0" } }, - "node_modules/apollo-server-caching": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.5.3.tgz", - "integrity": "sha512-iMi3087iphDAI0U2iSBE9qtx9kQoMMEWr6w+LwXruBD95ek9DWyj7OeC2U/ngLjRsXM43DoBDXlu7R+uMjahrQ==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.18.1.tgz", + "integrity": "sha512-/kvt0C5lRqGoCfsbmm7/CwMqoSkY3zzHLIjdhHZQW3VFrnz7ATecOHR7nb7V+xn4286MBxfnQfQhAmCI0u+bJA==", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" + "@typescript-eslint/types": "6.18.1", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": ">=6" + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/apollo-server-caching/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==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" + "balanced-match": "^1.0.0" } }, - "node_modules/apollo-server-caching/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/apollo-server-core": { - "version": "2.21.0", - "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.21.0.tgz", - "integrity": "sha512-GtIiq2F0dVDLzzIuO5+dK/pGq/sGxYlKCqAuQQqzYg0fvZ7fukyluXtcTe0tMI+FJZjU0j0WnKgiLsboCoAlPQ==", - "dev": true, - "dependencies": { - "@apollographql/apollo-tools": "^0.4.3", - "@apollographql/graphql-playground-html": "1.6.26", - "@apollographql/graphql-upload-8-fork": "^8.1.3", - "@types/ws": "^7.0.0", - "apollo-cache-control": "^0.11.6", - "apollo-datasource": "^0.7.3", - "apollo-graphql": "^0.6.0", - "apollo-reporting-protobuf": "^0.6.2", - "apollo-server-caching": "^0.5.3", - "apollo-server-env": "^3.0.0", - "apollo-server-errors": "^2.4.2", - "apollo-server-plugin-base": "^0.10.4", - "apollo-server-types": "^0.6.3", - "apollo-tracing": "^0.12.2", - "async-retry": "^1.2.1", - "fast-json-stable-stringify": "^2.0.0", - "graphql-extensions": "^0.12.8", - "graphql-tag": "^2.11.0", - "graphql-tools": "^4.0.8", - "loglevel": "^1.6.7", - "lru-cache": "^6.0.0", - "sha.js": "^2.4.11", - "subscriptions-transport-ws": "^0.9.11", - "uuid": "^8.0.0", - "ws": "^6.0.0" + "node_modules/@typescript-eslint/eslint-plugin/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=6" + "node": ">=16 || 14 >=14.17" }, - "peerDependencies": { - "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/apollo-server-core/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==", + "node_modules/@typescript-eslint/parser": { + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.18.1.tgz", + "integrity": "sha512-zct/MdJnVaRRNy9e84XnVtRv9Vf91/qqe+hZJtKanjojud4wAVy/7lXxJmMyX6X6J+xc6c//YEWvpeif8cAhWA==", "dev": true, "dependencies": { - "yallist": "^4.0.0" + "@typescript-eslint/scope-manager": "6.18.1", + "@typescript-eslint/types": "6.18.1", + "@typescript-eslint/typescript-estree": "6.18.1", + "@typescript-eslint/visitor-keys": "6.18.1", + "debug": "^4.3.4" }, "engines": { - "node": ">=10" + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/apollo-server-core/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/apollo-server-env": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-3.0.0.tgz", - "integrity": "sha512-tPSN+VttnPsoQAl/SBVUpGbLA97MXG990XIwq6YUnJyAixrrsjW1xYG7RlaOqetxm80y5mBZKLrRDiiSsW/vog==", + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.18.1.tgz", + "integrity": "sha512-BgdBwXPFmZzaZUuw6wKiHKIovms97a7eTImjkXCZE04TGHysG+0hDQPmygyvgtkoB/aOQwSM/nWv3LzrOIQOBw==", "dev": true, "dependencies": { - "node-fetch": "^2.1.2", - "util.promisify": "^1.0.0" + "@typescript-eslint/types": "6.18.1", + "@typescript-eslint/visitor-keys": "6.18.1" }, "engines": { - "node": ">=6" + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/apollo-server-errors": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-2.4.2.tgz", - "integrity": "sha512-FeGxW3Batn6sUtX3OVVUm7o56EgjxDlmgpTLNyWcLb0j6P8mw9oLNyAm3B+deHA4KNdNHO5BmHS2g1SJYjqPCQ==", + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.18.1.tgz", + "integrity": "sha512-4TuMAe+tc5oA7wwfqMtB0Y5OrREPF1GeJBAjqwgZh1lEMH5PJQgWgHGfYufVB51LtjD+peZylmeyxUXPfENLCw==", "dev": true, "engines": { - "node": ">=6" + "node": "^16.0.0 || >=18.0.0" }, - "peerDependencies": { - "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" - } - }, - "node_modules/apollo-server-express": { - "version": "2.21.0", - "resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-2.21.0.tgz", - "integrity": "sha512-zbOSNGuxUjlOFZnRrbMpga3pKDEroitF4NAqoVxgBivx7v2hGsE7rljct3PucTx2cMN90AyYe3cU4oA8jBxZIQ==", - "dev": true, - "dependencies": { - "@apollographql/graphql-playground-html": "1.6.26", - "@types/accepts": "^1.3.5", - "@types/body-parser": "1.19.0", - "@types/cors": "2.8.8", - "@types/express": "4.17.7", - "@types/express-serve-static-core": "4.17.18", - "accepts": "^1.3.5", - "apollo-server-core": "^2.21.0", - "apollo-server-types": "^0.6.3", - "body-parser": "^1.18.3", - "cors": "^2.8.4", - "express": "^4.17.1", - "graphql-subscriptions": "^1.0.0", - "graphql-tools": "^4.0.8", - "parseurl": "^1.3.2", - "subscriptions-transport-ws": "^0.9.16", - "type-is": "^1.6.16" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.18.1.tgz", + "integrity": "sha512-fv9B94UAhywPRhUeeV/v+3SBDvcPiLxRZJw/xZeeGgRLQZ6rLMG+8krrJUyIf6s1ecWTzlsbp0rlw7n9sjufHA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.18.1", + "@typescript-eslint/visitor-keys": "6.18.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": ">=6" + "node": "^16.0.0 || >=18.0.0" }, - "peerDependencies": { - "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/apollo-server-plugin-base": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.10.4.tgz", - "integrity": "sha512-HRhbyHgHFTLP0ImubQObYhSgpmVH4Rk1BinnceZmwudIVLKrqayIVOELdyext/QnSmmzg5W7vF3NLGBcVGMqDg==", + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.18.1.tgz", + "integrity": "sha512-/kvt0C5lRqGoCfsbmm7/CwMqoSkY3zzHLIjdhHZQW3VFrnz7ATecOHR7nb7V+xn4286MBxfnQfQhAmCI0u+bJA==", "dev": true, "dependencies": { - "apollo-server-types": "^0.6.3" + "@typescript-eslint/types": "6.18.1", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": ">=6" + "node": "^16.0.0 || >=18.0.0" }, - "peerDependencies": { - "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/apollo-server-plugin-response-cache": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/apollo-server-plugin-response-cache/-/apollo-server-plugin-response-cache-0.6.0.tgz", - "integrity": "sha512-Yjwec1VXINmNV6tmZLv+J9+iPb/4oKPcVA2YwF05o3Lf/oO+T5/9DP1yHxxjB117KDYlepKeIPuzAcqFZW/l8g==", + "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, "dependencies": { - "apollo-cache-control": "^0.11.6", - "apollo-server-caching": "^0.5.3", - "apollo-server-plugin-base": "^0.10.4" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=6" + "node": ">=16 || 14 >=14.17" }, - "peerDependencies": { - "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/apollo-server-types": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-0.6.3.tgz", - "integrity": "sha512-aVR7SlSGGY41E1f11YYz5bvwA89uGmkVUtzMiklDhZ7IgRJhysT5Dflt5IuwDxp+NdQkIhVCErUXakopocFLAg==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "dev": true, "dependencies": { - "apollo-reporting-protobuf": "^0.6.2", - "apollo-server-caching": "^0.5.3", - "apollo-server-env": "^3.0.0" + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" }, "engines": { - "node": ">=6" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "peerDependencies": { - "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/apollo-tracing": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.12.2.tgz", - "integrity": "sha512-SYN4o0C0wR1fyS3+P0FthyvsQVHFopdmN3IU64IaspR/RZScPxZ3Ae8uu++fTvkQflAkglnFM0aX6DkZERBp6w==", + "node_modules/@typescript-eslint/type-utils": { + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.18.1.tgz", + "integrity": "sha512-wyOSKhuzHeU/5pcRDP2G2Ndci+4g653V43gXTpt4nbyoIOAASkGDA9JIAgbQCdCkcr1MvpSYWzxTz0olCn8+/Q==", "dev": true, "dependencies": { - "apollo-server-env": "^3.0.0", - "apollo-server-plugin-base": "^0.10.4" + "@typescript-eslint/typescript-estree": "6.18.1", + "@typescript-eslint/utils": "6.18.1", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": ">=4.0" + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/apollo-utilities": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.3.4.tgz", - "integrity": "sha512-pk2hiWrCXMAy2fRPwEyhvka+mqwzeP60Jr1tRYi5xru+3ko94HI9o6lK0CT33/w4RDlxWchmdhDCrvdr+pHCig==", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": { + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.18.1.tgz", + "integrity": "sha512-BgdBwXPFmZzaZUuw6wKiHKIovms97a7eTImjkXCZE04TGHysG+0hDQPmygyvgtkoB/aOQwSM/nWv3LzrOIQOBw==", "dev": true, "dependencies": { - "@wry/equality": "^0.1.2", - "fast-json-stable-stringify": "^2.0.0", - "ts-invariant": "^0.4.0", - "tslib": "^1.10.0" + "@typescript-eslint/types": "6.18.1", + "@typescript-eslint/visitor-keys": "6.18.1" }, - "peerDependencies": { - "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/apollo-utilities/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/app-root-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.0.0.tgz", - "integrity": "sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.18.1.tgz", + "integrity": "sha512-4TuMAe+tc5oA7wwfqMtB0Y5OrREPF1GeJBAjqwgZh1lEMH5PJQgWgHGfYufVB51LtjD+peZylmeyxUXPfENLCw==", "dev": true, "engines": { - "node": ">= 6.0.0" + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/append-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", - "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.18.1.tgz", + "integrity": "sha512-fv9B94UAhywPRhUeeV/v+3SBDvcPiLxRZJw/xZeeGgRLQZ6rLMG+8krrJUyIf6s1ecWTzlsbp0rlw7n9sjufHA==", "dev": true, "dependencies": { - "buffer-equal": "^1.0.0" + "@typescript-eslint/types": "6.18.1", + "@typescript-eslint/visitor-keys": "6.18.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": ">=0.10.0" + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.18.1.tgz", + "integrity": "sha512-zZmTuVZvD1wpoceHvoQpOiewmWu3uP9FuTWo8vqpy2ffsmfCE8mklRPi+vmnIYAIk9t/4kOThri2QCDgor+OpQ==", "dev": true, "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/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, + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.18.1", + "@typescript-eslint/types": "6.18.1", + "@typescript-eslint/typescript-estree": "6.18.1", + "semver": "^7.5.4" + }, "engines": { - "node": ">=0.10.0" + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" } }, - "node_modules/arr-filter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", - "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.18.1.tgz", + "integrity": "sha512-/kvt0C5lRqGoCfsbmm7/CwMqoSkY3zzHLIjdhHZQW3VFrnz7ATecOHR7nb7V+xn4286MBxfnQfQhAmCI0u+bJA==", "dev": true, "dependencies": { - "make-iterator": "^1.0.0" + "@typescript-eslint/types": "6.18.1", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": ">=0.10.0" + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/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==", + "node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "balanced-match": "^1.0.0" } }, - "node_modules/arr-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", - "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=", + "node_modules/@typescript-eslint/type-utils/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, "dependencies": { - "make-iterator": "^1.0.0" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "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": ">=0.10.0" - } - }, - "node_modules/array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", - "dev": true, - "engines": { - "node": ">=0.10.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true - }, - "node_modules/array-initial": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", - "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=", + "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": { - "array-slice": "^1.0.0", - "is-number": "^4.0.0" + "@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": ">=0.10.0" + "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/array-initial/node_modules/is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "node_modules/@typescript-eslint/utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, "engines": { - "node": ">=0.10.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/array-last": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", - "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", + "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": { - "is-number": "^4.0.0" + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": ">=0.10.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/array-last/node_modules/is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true }, - "node_modules/array-slice": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", - "dev": true, + "node_modules/@whatwg-node/events": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", + "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", "engines": { - "node": ">=0.10.0" + "node": ">=16.0.0" } }, - "node_modules/array-sort": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", - "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", + "node_modules/@whatwg-node/fetch": { + "version": "0.9.14", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.14.tgz", + "integrity": "sha512-wurZC82zzZwXRDSW0OS9l141DynaJQh7Yt0FD1xZ8niX7/Et/7RoiLiltbVU1fSF1RR9z6ndEaTUQBAmddTm1w==", "dev": true, "dependencies": { - "default-compare": "^1.0.0", - "get-value": "^2.0.6", - "kind-of": "^5.0.2" + "@whatwg-node/node-fetch": "^0.5.0", + "urlpattern-polyfill": "^9.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=16.0.0" } }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "node_modules/@whatwg-node/node-fetch": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.0.tgz", + "integrity": "sha512-q76lDAafvHNGWedNAVHrz/EyYTS8qwRLcwne8SJQdRN5P3HydxU6XROFvJfTML6KZXQX2FDdGY4/SnaNyd7M0Q==", "dev": true, + "dependencies": { + "@whatwg-node/events": "^0.1.0", + "busboy": "^1.6.0", + "fast-querystring": "^1.1.1", + "fast-url-parser": "^1.1.3", + "tslib": "^2.3.1" + }, "engines": { - "node": ">=8" + "node": ">=16.0.0" } }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "node_modules/@whatwg-node/server": { + "version": "0.9.16", + "resolved": "https://registry.npmjs.org/@whatwg-node/server/-/server-0.9.16.tgz", + "integrity": "sha512-gktQkRyONEw2EGpx7UZaC6zNlUm21CGlqAHQXU3QC6W0zlLM5ZQNDCeD66q/nsPHDV08X2NTHlABsuAEk5rh/w==", "dev": true, + "dependencies": { + "@whatwg-node/fetch": "^0.9.10", + "tslib": "^2.3.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=16.0.0" } }, - "node_modules/asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "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==", "dev": true, "dependencies": { - "safer-buffer": "~2.1.0" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" } }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true, + "bin": { + "acorn": "bin/acorn" + }, "engines": { - "node": ">=0.8" + "node": ">=0.4.0" } }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "engines": { - "node": ">=0.10.0" + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.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==", + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true, "engines": { - "node": ">=8" + "node": ">=0.4.0" } }, - "node_modules/async-done": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz", - "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==", + "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==", "dev": true, "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.2", - "process-nextick-args": "^2.0.0", - "stream-exhaust": "^1.0.1" + "debug": "4" }, "engines": { - "node": ">= 0.10" + "node": ">= 6.0.0" } }, - "node_modules/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 - }, - "node_modules/async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, - "node_modules/async-retry": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.1.tgz", - "integrity": "sha512-aiieFW/7h3hY0Bq5d+ktDBejxuwR78vRu9hDUdR8rNhSaQ29VzPL4AoIRG7D/c7tdenwOcKvgPM6tIxB3cB6HA==", + "node_modules/agentkeepalive": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz", + "integrity": "sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==", "dev": true, "dependencies": { - "retry": "0.12.0" + "debug": "^4.1.0", + "depd": "^2.0.0", + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" } }, - "node_modules/async-settle": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", - "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=", + "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": { - "async-done": "^1.2.2" + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" }, "engines": { - "node": ">= 0.10" + "node": ">=8" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "node_modules/asyncro": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/asyncro/-/asyncro-3.0.0.tgz", - "integrity": "sha512-nEnWYfrBmA3taTiuiOoZYmgJ/CNrSoQLeLs29SeLcPu60yaw/mHDBHV0iOZ051fTvsTHxpCY+gXibqT9wbQYfg==", - "dev": true - }, - "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==", + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "engines": { - "node": ">= 4.0.0" + "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/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "node_modules/ansi-escape-sequences": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.1.0.tgz", + "integrity": "sha512-dzW9kHxH011uBsidTXd14JXgzye/YLb2LzeKZ4bsgl/Knwx8AtbSFkkGxagdNOoh0DlqHCmfiEjWKBaqjOanVw==", "dev": true, - "bin": { - "atob": "bin/atob.js" + "dependencies": { + "array-back": "^3.0.1" }, "engines": { - "node": ">= 4.5.0" + "node": ">=8.0.0" } }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "node_modules/ansi-escape-sequences/node_modules/array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", "dev": true, "engines": { - "node": "*" + "node": ">=6" } }, - "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true - }, - "node_modules/babel-jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", - "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", + "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": { - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/babel__core": "^7.1.7", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "slash": "^3.0.0" + "type-fest": "^0.21.3" }, "engines": { - "node": ">= 10.14.2" + "node": ">=8" }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/babel-jest/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "node_modules/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, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/babel-plugin-istanbul": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", - "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "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==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^4.0.0", - "test-exclude": "^6.0.0" - }, "engines": { "node": ">=8" } }, - "node_modules/babel-plugin-jest-hoist": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", - "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", + "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": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" + "color-convert": "^2.0.1" }, "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" + "node": ">=8" }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/babel-preset-jest": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", - "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", + "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, "dependencies": { - "babel-plugin-jest-hoist": "^26.6.2", - "babel-preset-current-node-syntax": "^1.0.0" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" }, "engines": { - "node": ">= 10.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": ">= 8" } }, - "node_modules/bach": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", - "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=", + "node_modules/app-root-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz", + "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==", "dev": true, - "dependencies": { - "arr-filter": "^1.1.1", - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "array-each": "^1.0.0", - "array-initial": "^1.0.0", - "array-last": "^1.1.1", - "async-done": "^1.2.2", - "async-settle": "^1.0.0", - "now-and-later": "^2.0.0" - }, "engines": { - "node": ">= 0.10" + "node": ">= 6.0.0" } }, - "node_modules/backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true }, - "node_modules/balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "node_modules/array-back": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", + "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", "dev": true, "dependencies": { - "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" + "typical": "^2.6.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/base/node_modules/define-property": { + "node_modules/array-buffer-byte-length": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", "dev": true, "dependencies": { - "is-descriptor": "^1.0.0" + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "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==", - "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/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "node_modules/array-includes": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", "dev": true, "dependencies": { - "tweetnacl": "^0.14.3" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "node_modules/array-timsort": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz", + "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==", + "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/binaryextensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-2.3.0.tgz", - "integrity": "sha512-nAihlQsYGyc5Bwq6+EsubvANYGExeJKHDO3RjnvwU042fawQTQfM3Kxn7IHUXQOz4bzfwsGYYHGSvXyW4zOGLg==", + "node_modules/array.prototype.findlastindex": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", + "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + }, "engines": { - "node": ">=0.8" + "node": ">= 0.4" }, "funding": { - "url": "https://bevry.me/fund" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", "dev": true, - "optional": true, "dependencies": { - "file-uri-to-path": "1.0.0" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/bl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", - "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, "dependencies": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", - "dev": true - }, - "node_modules/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", + "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", "dev": true, "dependencies": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" }, "engines": { - "node": ">= 0.8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "engines": { + "node": ">=0.8" } }, - "node_modules/body-parser/node_modules/http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "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==", "dev": true, "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" + "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==", + "dev": true + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, + "engines": { + "node": ">= 0.4" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, "engines": { - "node": ">= 0.6" + "node": "*" } }, - "node_modules/body-parser/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "node_modules/aws4": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", "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==", + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" } }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "node_modules/bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", "dev": true, "dependencies": { - "fast-json-stable-stringify": "2.x" + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" }, "engines": { - "node": ">= 6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", "dev": true, "dependencies": { - "node-int64": "^0.4.0" + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/bson": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.5.tgz", - "integrity": "sha512-kDuEzldR21lHciPQAIulLs1LZlCXdLziXI6Mb/TDkwXhb//UORJNPXgcRs2CuO4H0DcMkpfT3/ySsP3unoZjBg==", + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, "engines": { - "node": ">=0.6.19" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "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==", + "dev": true + }, + "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==", "dev": true, "funding": [ { @@ -3390,140 +4483,248 @@ "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==", + "dev": true, "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "tweetnacl": "^0.14.3" } }, - "node_modules/buffer-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", - "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", + "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, - "engines": { - "node": ">=0.4.0" + "dependencies": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" } }, - "node_modules/buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "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/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==", - "dev": true, - "engines": { - "node": ">=4" - } + "node_modules/boolean": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", + "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", + "dev": true }, - "node_modules/builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "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==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/busboy": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.3.1.tgz", - "integrity": "sha512-y7tTxhGKXcyBxRKAni+awqx8uqaJKrSFSNFSeRG5CsWNdmy2BIK+6VGWEW7TZnIO/533mtMEA4rOevQV815YJw==", + "node_modules/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": { - "dicer": "0.3.0" + "fill-range": "^7.0.1" }, "engines": { - "node": ">=4.5.0" + "node": ">=8" } }, - "node_modules/bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "node_modules/browserslist": { + "version": "4.21.9", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", + "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", "dev": true, - "engines": { - "node": ">= 0.8" - } + "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.30001503", + "electron-to-chromium": "^1.4.431", + "node-releases": "^2.0.12", + "update-browserslist-db": "^1.0.11" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } }, - "node_modules/cacache": { - "version": "15.0.5", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.5.tgz", - "integrity": "sha512-lloiL22n7sOjEEXdL8NAjTgv9a1u43xICE9/203qonkZUCj5X1UEWIdf2/Y0d6QcCtMzbKQyhrcDbdvlZTs/+A==", + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", "dev": true, "dependencies": { - "@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.0", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" + "fast-json-stable-stringify": "2.x" }, "engines": { - "node": ">= 10" + "node": ">= 6" } }, - "node_modules/cacache/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==", + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, "dependencies": { - "yallist": "^4.0.0" - }, + "node-int64": "^0.4.0" + } + }, + "node_modules/bson": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-5.5.0.tgz", + "integrity": "sha512-B+QB4YmDx9RStKv8LLSl/aVIEV3nYJc3cJNNTK2Cd1TL+7P+cNpw9mAPeCgc5K+j01Dv6sxUzcITXDx7ZU3F0w==", + "dev": true, + "optional": true, + "peer": true, "engines": { - "node": ">=10" + "node": ">=14.20.1" } }, - "node_modules/cacache/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/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "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.2.1" + } + }, + "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/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "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-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-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", "dev": true, "dependencies": { - "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" + "streamsearch": "^1.1.0" }, "engines": { - "node": ">=0.10.0" + "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==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.1.3.tgz", + "integrity": "sha512-jAdjGxmPxZh0IipMdR7fK/4sDSrHMLUV0+GvVUsjwyGNKHsh79kW/otg+GkbXwl6Uzvy9wsvHOX4nUoWldeZMg==", + "dev": true, + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/cacache/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/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3547,186 +4748,123 @@ "node": ">=6" } }, - "node_modules/capture-exit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", - "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "node_modules/caniuse-lite": { + "version": "1.0.30001514", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001514.tgz", + "integrity": "sha512-ENcIpYBmwAAOm/V2cXgM7rZUrKKaqisZl4ZAI520FIkqGXUxJjmaIssbRW5HVVR5tyV6ygTLIm15aU8LUmQSaQ==", "dev": true, - "dependencies": { - "rsvp": "^4.8.4" - }, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } + "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/caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", "dev": true }, "node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "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": ">=8" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true, "engines": { "node": ">=10" - } - }, - "node_modules/chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "dev": true, - "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.1" - } - }, - "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" + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "node_modules/cjs-module-lexer": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", - "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", - "dev": true - }, - "node_modules/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==", + "node_modules/chalk-template": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-1.1.0.tgz", + "integrity": "sha512-T2VJbcDuZQ0Tb2EWwSotMPJjgpy1/tGee1BTpUNsGZ/qgNjV2t7Mvu+d4600U564nbLesN1x2dPL+xii174Ekg==", "dev": true, "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" + "chalk": "^5.2.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/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, - "dependencies": { - "is-descriptor": "^0.1.0" + "node": ">=14.16" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/chalk/chalk-template?sponsor=1" } }, - "node_modules/class-utils/node_modules/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=", + "node_modules/chalk-template/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/class-utils/node_modules/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=", + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/class-utils/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "node_modules/ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, + "node_modules/cjs-module-lexer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", + "dev": true + }, "node_modules/class-validator": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.13.1.tgz", - "integrity": "sha512-zWIeYFhUitvAHBwNhDdCRK09hWx+P0HUwFE8US8/CxFpMVzkUK8RJl7yOIE+BVu2lxyPNgeOaFv78tLE47jBIg==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.14.0.tgz", + "integrity": "sha512-ct3ltplN8I9fOwUd8GrP8UQixwff129BkEtuWDKL5W45cQuLd19xqmTLu5ge78YDm/fdje6FMt0hGOhl0lii3A==", "dev": true, "dependencies": { - "@types/validator": "^13.1.3", - "libphonenumber-js": "^1.9.7", - "validator": "^13.5.2" + "@types/validator": "^13.7.10", + "libphonenumber-js": "^1.10.14", + "validator": "^13.7.0" } }, "node_modules/clean-stack": { @@ -3738,26 +4876,45 @@ "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==", + "node_modules/clear-module": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/clear-module/-/clear-module-4.1.2.tgz", + "integrity": "sha512-LWAxzHqdHsAZlPlEyJ2Poz6AIs384mPeqLVCru2p0BrP9G/kVGuhNyZYClLO6cXlnuJjzC8xtsJIuMjKqLXoAw==", "dev": true, "dependencies": { - "restore-cursor": "^3.1.0" + "parent-module": "^2.0.0", + "resolve-from": "^5.0.0" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cli-highlight": { - "version": "2.1.10", - "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.10.tgz", - "integrity": "sha512-CcPFD3JwdQ2oSzy+AMG6j3LRTkNjM82kzcSKzoVw6cLanDCJNlsLjeqVTOTfOfucnWv5F0rmBemVf1m9JiIasw==", + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", + "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "highlight.js": "^10.0.0", + "highlight.js": "^10.7.1", "mz": "^2.4.0", "parse5": "^5.1.1", "parse5-htmlparser2-tree-adapter": "^6.0.0", @@ -3771,22 +4928,6 @@ "npm": ">=5.0.0" } }, - "node_modules/cli-highlight/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "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/cli-highlight/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -3798,39 +4939,33 @@ "wrap-ansi": "^7.0.0" } }, - "node_modules/cli-highlight/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==", + "node_modules/cli-highlight/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==", + "dev": true + }, + "node_modules/cli-highlight/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==", "dev": true, "engines": { - "node": "6.* || 8.* || >= 10.*" + "node": ">=8" } }, - "node_modules/cli-highlight/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==", + "node_modules/cli-highlight/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==", "dev": true, "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/cli-highlight/node_modules/y18n": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", - "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", - "dev": true, "engines": { - "node": ">=10" + "node": ">=8" } }, "node_modules/cli-highlight/node_modules/yargs": { @@ -3851,132 +4986,183 @@ "node": ">=10" } }, + "node_modules/cli-highlight/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/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==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", "dev": true, "dependencies": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.0.0.tgz", + "integrity": "sha512-GPQHj7row82Hjo9hKZieKcHIhaAIKOJvFSIZXuCU9OASVZrMNUaZuz++SPVrBjnLsnk4k+z9f2EIypgxf2vNFw==", "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cliui/node_modules/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=", + "node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "dependencies": { - "number-is-nan": "^1.0.0" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/cliui/node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "node_modules/cliss": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/cliss/-/cliss-0.0.2.tgz", + "integrity": "sha512-6rj9pgdukjT994Md13JCUAgTk91abAKrygL9sAvmHY4F6AKMOV8ccGaxhUUfcBuyg3sundWnn3JE0Mc9W6ZYqw==", "dev": true, "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" + "command-line-usage": "^4.0.1", + "deepmerge": "^2.0.0", + "get-stdin": "^5.0.1", + "inspect-parameters-declaration": "0.0.9", + "object-to-arguments": "0.0.8", + "pipe-functions": "^1.3.0", + "strip-ansi": "^4.0.0", + "yargs-parser": "^7.0.0" } }, - "node_modules/cliui/node_modules/strip-ansi": { + "node_modules/cliss/node_modules/ansi-regex": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "node_modules/cliss/node_modules/deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", "dev": true, - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, "engines": { "node": ">=0.10.0" } }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "node_modules/cliss/node_modules/get-stdin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", + "integrity": "sha512-jZV7n6jGE3Gt7fgSTJoz91Ak5MuTLwMwkoYdjxuJ/AmjIsE1UC03y/IWkZCQGEvVNS9qoRNwy5BCqxImv0FVeA==", "dev": true, "engines": { - "node": ">=0.8" + "node": ">=0.12.0" } }, - "node_modules/clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", + "node_modules/cliss/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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": ">= 0.10" + "node": ">=12" } }, - "node_modules/clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "node_modules/cliui/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==", "dev": true }, - "node_modules/cloneable-readable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", - "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", + "node_modules/cliui/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/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==", "dev": true, "dependencies": { - "inherits": "^2.0.1", - "process-nextick-args": "^2.0.0", - "readable-stream": "^2.3.5" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, "node_modules/cluster-key-slot": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz", - "integrity": "sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==", + "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==", "dev": true, "engines": { "node": ">=0.10.0" @@ -3985,53 +5171,30 @@ "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true, "engines": { "iojs": ">= 1.0.0", "node": ">= 0.12.0" } }, - "node_modules/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=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", "dev": true }, - "node_modules/collection-map": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", - "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=", - "dev": true, - "dependencies": { - "arr-map": "^2.0.2", - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", "dev": true, "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" + "color-convert": "^2.0.1", + "color-string": "^1.9.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=12.5.0" } }, "node_modules/color-convert": { @@ -4052,19 +5215,20 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "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==", + "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==", "dev": true, - "bin": { - "color-support": "bin.js" + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" } }, "node_modules/colorette": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", - "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", "dev": true }, "node_modules/combined-stream": { @@ -4079,81 +5243,117 @@ "node": ">= 0.8" } }, - "node_modules/commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "node_modules/command-line-usage": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-4.1.0.tgz", + "integrity": "sha512-MxS8Ad995KpdAC0Jopo/ovGIroV/m0KHwzKfXxKag6FHOkGsH8/lv5yjgablcRxCJJC0oJeUMuO/gmaq+Wq46g==", "dev": true, + "dependencies": { + "ansi-escape-sequences": "^4.0.0", + "array-back": "^2.0.0", + "table-layout": "^0.4.2", + "typical": "^2.6.1" + }, "engines": { - "node": ">= 6" + "node": ">=4.0.0" } }, - "node_modules/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 + "node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true, + "engines": { + "node": ">=16" + } }, - "node_modules/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 + "node_modules/comment-json": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.2.3.tgz", + "integrity": "sha512-SsxdiOf064DWoZLH799Ata6u7iV658A11PlWtZATDlXPpKGJnbJZ5Z24ybixAi+LUUqJ/GKowAejtC5GFUG7Tw==", + "dev": true, + "dependencies": { + "array-timsort": "^1.0.3", + "core-util-is": "^1.0.3", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">= 6" + } }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "node_modules/configstore": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", + "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", "dev": true, - "engines": [ - "node >= 0.8" - ], "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" + "dot-prop": "^6.0.1", + "graceful-fs": "^4.2.6", + "unique-string": "^3.0.0", + "write-file-atomic": "^3.0.3", + "xdg-basedir": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/yeoman/configstore?sponsor=1" + } + }, + "node_modules/confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", + "dev": true + }, + "node_modules/consola": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.2.3.tgz", + "integrity": "sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==", + "dev": true, + "engines": { + "node": "^14.18.0 || >=16.10.0" } }, "node_modules/content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dev": true, "dependencies": { - "safe-buffer": "5.1.2" + "safe-buffer": "5.2.1" }, "engines": { "node": ">= 0.6" } }, "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.1" - } + "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/cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "dev": true, "engines": { "node": ">= 0.6" @@ -4162,43 +5362,13 @@ "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "dev": true }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/copy-props": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.4.tgz", - "integrity": "sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==", - "dev": true, - "dependencies": { - "each-props": "^1.3.0", - "is-plain-object": "^2.0.1" - } - }, - "node_modules/core-js": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.2.tgz", - "integrity": "sha512-FfApuSRgrR6G5s58casCBd9M2k+4ikuu4wbW6pJyYU7bd9zvFc9qf7vr5xmrZOhT9nn+8uwlH1oRR9jTnFoA3A==", - "dev": true, - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "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 }, "node_modules/cors": { @@ -4214,20 +5384,25 @@ "node": ">= 0.10" } }, - "node_modules/cosmiconfig": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", - "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", "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" + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" }, "engines": { - "node": ">=10" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/create-require": { @@ -4236,13 +5411,16 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, - "node_modules/cross-fetch": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.0.6.tgz", - "integrity": "sha512-KBPUbqgFjzWlVcURG+Svp9TlhA5uliYtiNx/0r8nv0pdypeQCRJ9IaSIc3q/x3q8t3F75cHuwxVql1HFGHCNJQ==", + "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==", "dev": true, "dependencies": { - "node-fetch": "2.6.1" + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" } }, "node_modules/cross-spawn": { @@ -4259,3117 +5437,3250 @@ "node": ">= 8" } }, - "node_modules/cssfilter": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz", - "integrity": "sha1-xtJnJjKi5cg+AT5oZKQs6N79IK4=", - "dev": true - }, - "node_modules/cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true - }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "node_modules/crypto-random-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", + "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", "dev": true, "dependencies": { - "cssom": "~0.3.6" + "type-fest": "^1.0.1" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - }, - "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==", + "node_modules/crypto-random-string/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", "dev": true, - "dependencies": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "node_modules/cspell": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/cspell/-/cspell-8.7.0.tgz", + "integrity": "sha512-77nRPgLl240C6FK8RKVKo34lP15Lzp/6bk+SKYJFwUKKXlcgWXDis+Lw4JolA741/JgHtuxmhW1C8P7dCKjJ3w==", + "dev": true, + "dependencies": { + "@cspell/cspell-json-reporter": "8.7.0", + "@cspell/cspell-pipe": "8.7.0", + "@cspell/cspell-types": "8.7.0", + "@cspell/dynamic-import": "8.7.0", + "chalk": "^5.3.0", + "chalk-template": "^1.1.0", + "commander": "^12.0.0", + "cspell-gitignore": "8.7.0", + "cspell-glob": "8.7.0", + "cspell-io": "8.7.0", + "cspell-lib": "8.7.0", + "fast-glob": "^3.3.2", + "fast-json-stable-stringify": "^2.1.0", + "file-entry-cache": "^8.0.0", + "get-stdin": "^9.0.0", + "semver": "^7.6.0", + "strip-ansi": "^7.1.0", + "vscode-uri": "^3.0.8" + }, + "bin": { + "cspell": "bin.mjs", + "cspell-esm": "bin.mjs" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/streetsidesoftware/cspell?sponsor=1" + } + }, + "node_modules/cspell-config-lib": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/cspell-config-lib/-/cspell-config-lib-8.3.2.tgz", + "integrity": "sha512-Wc98XhBNLwDxnxCzMtgRJALI9a69cu3C5Gf1rGjNTKSFo9JYiQmju0Ur3z25Pkx9Sa86f+2IjvNCf33rUDSoBQ==", "dev": true, "dependencies": { - "assert-plus": "^1.0.0" + "@cspell/cspell-types": "8.3.2", + "comment-json": "^4.2.3", + "yaml": "^2.3.4" }, "engines": { - "node": ">=0.10" + "node": ">=18" } }, - "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "node_modules/cspell-dictionary": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/cspell-dictionary/-/cspell-dictionary-8.3.2.tgz", + "integrity": "sha512-xyK95hO2BMPFxIo8zBwGml8035qOxSBdga1BMhwW/p2wDrQP8S4Cdm/54//tCDmKn6uRkFQvyOfWGaX2l8WMEg==", "dev": true, "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" + "@cspell/cspell-pipe": "8.3.2", + "@cspell/cspell-types": "8.3.2", + "cspell-trie-lib": "8.3.2", + "fast-equals": "^5.0.1", + "gensequence": "^6.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" } }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/cspell-gitignore": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/cspell-gitignore/-/cspell-gitignore-8.7.0.tgz", + "integrity": "sha512-yvUZ86qyopUpDgn+YXP1qTpUe/lp65ZFvpMtw21lWHTFlg1OWKntr349EQU/5ben/K6koxk1FiElCBV7Lr4uFg==", "dev": true, "dependencies": { - "ms": "2.0.0" + "cspell-glob": "8.7.0", + "find-up-simple": "^1.0.0" + }, + "bin": { + "cspell-gitignore": "bin.mjs" + }, + "engines": { + "node": ">=18" } }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "node_modules/cspell-gitignore/node_modules/cspell-glob": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/cspell-glob/-/cspell-glob-8.7.0.tgz", + "integrity": "sha512-AMdfx0gvROA/aIL8t8b5Y5NtMgscGZELFj6WhCSZiQSuWRxXUKiLGGLUFjx2y0hgXN9LUYOo6aBjvhnxI/v71g==", "dev": true, + "dependencies": { + "micromatch": "^4.0.5" + }, "engines": { - "node": ">=0.10.0" + "node": ">=18" } }, - "node_modules/decimal.js": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", - "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==", - "dev": true - }, - "node_modules/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=", + "node_modules/cspell-glob": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/cspell-glob/-/cspell-glob-8.3.2.tgz", + "integrity": "sha512-KtIFxE+3l5dGEofND4/CdZffXP8XN1+XGQKxJ96lIzWsc01mkotfhxTkla6mgvfH039t7BsY/SWv0460KyGslQ==", "dev": true, + "dependencies": { + "micromatch": "^4.0.5" + }, "engines": { - "node": ">=0.10" + "node": ">=18" } }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", - "dev": true - }, - "node_modules/deep-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 - }, - "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "node_modules/cspell-grammar": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/cspell-grammar/-/cspell-grammar-8.3.2.tgz", + "integrity": "sha512-tYCkOmRzJe1a6/R+8QGSwG7TwTgznLPqsHtepKzLmnS4YX54VXjKRI9zMARxXDzUVfyCSVdW5MyiY/0WTNoy+A==", "dev": true, + "dependencies": { + "@cspell/cspell-pipe": "8.3.2", + "@cspell/cspell-types": "8.3.2" + }, + "bin": { + "cspell-grammar": "bin.mjs" + }, "engines": { - "node": ">=0.10.0" + "node": ">=18" } }, - "node_modules/default-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", - "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", + "node_modules/cspell-io": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/cspell-io/-/cspell-io-8.3.2.tgz", + "integrity": "sha512-WYpKsyBCQP0SY4gXnhW5fPuxcYchKYKG1PIXVV3ezFU4muSgW6GuLNbGuSfwv/8YNXRgFSN0e3hYH0rdBK2Aow==", "dev": true, "dependencies": { - "kind-of": "^5.0.2" + "@cspell/cspell-service-bus": "8.3.2" }, "engines": { - "node": ">=0.10.0" + "node": ">=18" } }, - "node_modules/default-resolution": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", - "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=", + "node_modules/cspell-lib": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-8.3.2.tgz", + "integrity": "sha512-wTvdaev/TyGB/ln6CVD1QbVs2D7/+QiajQ67S7yj1suLHM6YcNQQb/5sPAM8VPtj0E7PgwgPXf3bq18OtPvnFg==", + "dev": true, + "dependencies": { + "@cspell/cspell-bundled-dicts": "8.3.2", + "@cspell/cspell-pipe": "8.3.2", + "@cspell/cspell-resolver": "8.3.2", + "@cspell/cspell-types": "8.3.2", + "@cspell/dynamic-import": "8.3.2", + "@cspell/strong-weak-map": "8.3.2", + "clear-module": "^4.1.2", + "comment-json": "^4.2.3", + "configstore": "^6.0.0", + "cspell-config-lib": "8.3.2", + "cspell-dictionary": "8.3.2", + "cspell-glob": "8.3.2", + "cspell-grammar": "8.3.2", + "cspell-io": "8.3.2", + "cspell-trie-lib": "8.3.2", + "fast-equals": "^5.0.1", + "gensequence": "^6.0.0", + "import-fresh": "^3.3.0", + "resolve-from": "^5.0.0", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-uri": "^3.0.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cspell-trie-lib": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/cspell-trie-lib/-/cspell-trie-lib-8.3.2.tgz", + "integrity": "sha512-8qh2FqzkLMwzlTlvO/5Z+89fhi30rrfekocpight/BmqKbE2XFJQD7wS2ml24e7q/rdHJLXVpJbY/V5mByucCA==", "dev": true, + "dependencies": { + "@cspell/cspell-pipe": "8.3.2", + "@cspell/cspell-types": "8.3.2", + "gensequence": "^6.0.0" + }, "engines": { - "node": ">= 0.10" + "node": ">=18" } }, - "node_modules/define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "node_modules/cspell/node_modules/@cspell/cspell-bundled-dicts": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-8.7.0.tgz", + "integrity": "sha512-B5YQI7Dd9m0JHTmHgs7PiyP4BWXzl8ixpK+HGOwhxzh7GyfFt1Eo/gxMxBDX/9SaewEzeb2OjRpRKEFtEsto3A==", "dev": true, "dependencies": { - "object-keys": "^1.0.12" + "@cspell/dict-ada": "^4.0.2", + "@cspell/dict-aws": "^4.0.1", + "@cspell/dict-bash": "^4.1.3", + "@cspell/dict-companies": "^3.0.31", + "@cspell/dict-cpp": "^5.1.3", + "@cspell/dict-cryptocurrencies": "^5.0.0", + "@cspell/dict-csharp": "^4.0.2", + "@cspell/dict-css": "^4.0.12", + "@cspell/dict-dart": "^2.0.3", + "@cspell/dict-django": "^4.1.0", + "@cspell/dict-docker": "^1.1.7", + "@cspell/dict-dotnet": "^5.0.0", + "@cspell/dict-elixir": "^4.0.3", + "@cspell/dict-en_us": "^4.3.17", + "@cspell/dict-en-common-misspellings": "^2.0.0", + "@cspell/dict-en-gb": "1.1.33", + "@cspell/dict-filetypes": "^3.0.3", + "@cspell/dict-fonts": "^4.0.0", + "@cspell/dict-fsharp": "^1.0.1", + "@cspell/dict-fullstack": "^3.1.5", + "@cspell/dict-gaming-terms": "^1.0.5", + "@cspell/dict-git": "^3.0.0", + "@cspell/dict-golang": "^6.0.5", + "@cspell/dict-haskell": "^4.0.1", + "@cspell/dict-html": "^4.0.5", + "@cspell/dict-html-symbol-entities": "^4.0.0", + "@cspell/dict-java": "^5.0.6", + "@cspell/dict-julia": "^1.0.1", + "@cspell/dict-k8s": "^1.0.2", + "@cspell/dict-latex": "^4.0.0", + "@cspell/dict-lorem-ipsum": "^4.0.0", + "@cspell/dict-lua": "^4.0.3", + "@cspell/dict-makefile": "^1.0.0", + "@cspell/dict-monkeyc": "^1.0.6", + "@cspell/dict-node": "^4.0.3", + "@cspell/dict-npm": "^5.0.15", + "@cspell/dict-php": "^4.0.6", + "@cspell/dict-powershell": "^5.0.3", + "@cspell/dict-public-licenses": "^2.0.6", + "@cspell/dict-python": "^4.1.11", + "@cspell/dict-r": "^2.0.1", + "@cspell/dict-ruby": "^5.0.2", + "@cspell/dict-rust": "^4.0.2", + "@cspell/dict-scala": "^5.0.0", + "@cspell/dict-software-terms": "^3.3.18", + "@cspell/dict-sql": "^2.1.3", + "@cspell/dict-svelte": "^1.0.2", + "@cspell/dict-swift": "^2.0.1", + "@cspell/dict-terraform": "^1.0.0", + "@cspell/dict-typescript": "^3.1.2", + "@cspell/dict-vue": "^3.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=18" } }, - "node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "node_modules/cspell/node_modules/@cspell/cspell-pipe": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@cspell/cspell-pipe/-/cspell-pipe-8.7.0.tgz", + "integrity": "sha512-ePqddIQ4arqPQgOkC146SkZxvZb9/jL7xIM5Igy2n3tiWTC5ijrX/mbHpPZ1VGcFck+1M0cJUuyhuJk+vMj3rg==", "dev": true, - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, "engines": { - "node": ">=0.10.0" + "node": ">=18" } }, - "node_modules/del": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/del/-/del-6.0.0.tgz", - "integrity": "sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ==", + "node_modules/cspell/node_modules/@cspell/cspell-resolver": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@cspell/cspell-resolver/-/cspell-resolver-8.7.0.tgz", + "integrity": "sha512-grZwDFYqcBYQDaz4AkUtdyqc4UUH2J3/7yWVkBbYDPE+FQHa9ofFXzXxyjs56GJlPfi9ULpe5/Wz6uVLg8rQkQ==", "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" + "global-directory": "^4.0.1" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=18" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "node_modules/cspell/node_modules/@cspell/cspell-service-bus": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@cspell/cspell-service-bus/-/cspell-service-bus-8.7.0.tgz", + "integrity": "sha512-KW48iu0nTDzbedixc7iB7K7mlAZQ7QeMLuM/akxigOlvtOdVJrRa9Pfn44lwejts1ANb/IXil3GH8YylkVi76Q==", "dev": true, "engines": { - "node": ">=0.4.0" + "node": ">=18" } }, - "node_modules/denque": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz", - "integrity": "sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ==", + "node_modules/cspell/node_modules/@cspell/cspell-types": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@cspell/cspell-types/-/cspell-types-8.7.0.tgz", + "integrity": "sha512-Rb+LCE5I9JEb/LE8nSViVSF8z1CWv/z4mPBIG37VMa7aUx2gAQa6gJekNfpY9YZiMzx4Tv3gDujN80ytks4pGA==", "dev": true, "engines": { - "node": ">=0.10" + "node": ">=18" } }, - "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "node_modules/cspell/node_modules/@cspell/dynamic-import": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@cspell/dynamic-import/-/dynamic-import-8.7.0.tgz", + "integrity": "sha512-xlEPdiHVDu+4xYkvwjL9MgklxOi9XB+Pr1H9s3Ww9WEq+q6BA3xOHxLIU/k8mhqFTMZGFZRCsdy/EwMu6SyRhQ==", "dev": true, + "dependencies": { + "import-meta-resolve": "^4.0.0" + }, "engines": { - "node": ">= 0.6" + "node": ">=18.0" } }, - "node_modules/deprecated-decorator": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz", - "integrity": "sha1-AJZjF7ehL+kvPMgx91g68ym4bDc=", - "dev": true - }, - "node_modules/destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "node_modules/detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "node_modules/cspell/node_modules/@cspell/strong-weak-map": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@cspell/strong-weak-map/-/strong-weak-map-8.7.0.tgz", + "integrity": "sha512-0bo0WwDr2lzGoCP7vbpWbDpPyuOrHKK+218txnUpx6Pn1EDBLfcDQsiZED5B6zlpwgbGi6y3vc0rWtJbjKvwzg==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=18" } }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "node_modules/cspell/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, "engines": { - "node": ">=8" - } - }, - "node_modules/dicer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz", - "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==", - "dev": true, - "dependencies": { - "streamsearch": "0.1.2" + "node": ">=12" }, - "engines": { - "node": ">=4.5.0" + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "node_modules/cspell/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true, "engines": { - "node": ">=0.3.1" + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "node_modules/cspell/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==", "dev": true, "engines": { - "node": ">= 10.14.2" + "node": ">=18" } }, - "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==", + "node_modules/cspell/node_modules/cspell-config-lib": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/cspell-config-lib/-/cspell-config-lib-8.7.0.tgz", + "integrity": "sha512-depsd01GbLBo71/tfRrL5iECWQLS4CjCxA9C01dVkFAJqVB0s+K9KLKjTlq5aHOhcvo9Z3dHV+bGQCf5/Q7bfw==", "dev": true, "dependencies": { - "path-type": "^4.0.0" + "@cspell/cspell-types": "8.7.0", + "comment-json": "^4.2.3", + "yaml": "^2.4.1" }, "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/doctrine": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-0.7.2.tgz", - "integrity": "sha1-fLhgNZujvpDgQLJrcpzkv6ZUxSM=", + "node_modules/cspell/node_modules/cspell-dictionary": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/cspell-dictionary/-/cspell-dictionary-8.7.0.tgz", + "integrity": "sha512-S6IpZSzIMxlOO/33NgCOuP0TPH2mZbw8d5CP44z5jajflloq8l74MeJLkeDzYfCRcm0Rtk0A5drBeMg+Ai34OA==", "dev": true, "dependencies": { - "esutils": "^1.1.6", - "isarray": "0.0.1" + "@cspell/cspell-pipe": "8.7.0", + "@cspell/cspell-types": "8.7.0", + "cspell-trie-lib": "8.7.0", + "fast-equals": "^5.0.1", + "gensequence": "^7.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=18" } }, - "node_modules/doctrine/node_modules/esutils": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz", - "integrity": "sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U=", + "node_modules/cspell/node_modules/cspell-glob": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/cspell-glob/-/cspell-glob-8.7.0.tgz", + "integrity": "sha512-AMdfx0gvROA/aIL8t8b5Y5NtMgscGZELFj6WhCSZiQSuWRxXUKiLGGLUFjx2y0hgXN9LUYOo6aBjvhnxI/v71g==", "dev": true, + "dependencies": { + "micromatch": "^4.0.5" + }, "engines": { - "node": ">=0.10.0" + "node": ">=18" } }, - "node_modules/doctrine/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "node_modules/domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "node_modules/cspell/node_modules/cspell-grammar": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/cspell-grammar/-/cspell-grammar-8.7.0.tgz", + "integrity": "sha512-SGcXc7322wU2WNRi7vtpToWDXTqZHhxqvR+aIXHT2kkxlMSWp3Rvfpshd0ckgY54nZtgw7R/JtKND2jeACRpwQ==", "dev": true, "dependencies": { - "webidl-conversions": "^5.0.0" + "@cspell/cspell-pipe": "8.7.0", + "@cspell/cspell-types": "8.7.0" + }, + "bin": { + "cspell-grammar": "bin.mjs" }, "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/domexception/node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "node_modules/cspell/node_modules/cspell-io": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/cspell-io/-/cspell-io-8.7.0.tgz", + "integrity": "sha512-o7OltyyvVkRG1gQrIqGpN5pUkHNnv6rvihb7Qu6cJ8jITinLGuWJuEQpgt0eF5yIr624jDbFwSzAxsFox8riQg==", "dev": true, + "dependencies": { + "@cspell/cspell-service-bus": "8.7.0" + }, "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/dotenv": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", - "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==", + "node_modules/cspell/node_modules/cspell-lib": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-8.7.0.tgz", + "integrity": "sha512-qDSHZGekwiDmouYRECTQokE+hgAuPqREm+Hb+G3DoIo3ZK5H47TtEUo8fNCw22XsKefcF8X28LiyoZwiYHVpSg==", "dev": true, + "dependencies": { + "@cspell/cspell-bundled-dicts": "8.7.0", + "@cspell/cspell-pipe": "8.7.0", + "@cspell/cspell-resolver": "8.7.0", + "@cspell/cspell-types": "8.7.0", + "@cspell/dynamic-import": "8.7.0", + "@cspell/strong-weak-map": "8.7.0", + "clear-module": "^4.1.2", + "comment-json": "^4.2.3", + "configstore": "^6.0.0", + "cspell-config-lib": "8.7.0", + "cspell-dictionary": "8.7.0", + "cspell-glob": "8.7.0", + "cspell-grammar": "8.7.0", + "cspell-io": "8.7.0", + "cspell-trie-lib": "8.7.0", + "fast-equals": "^5.0.1", + "gensequence": "^7.0.0", + "import-fresh": "^3.3.0", + "resolve-from": "^5.0.0", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-uri": "^3.0.8" + }, "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "node_modules/cspell/node_modules/cspell-trie-lib": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/cspell-trie-lib/-/cspell-trie-lib-8.7.0.tgz", + "integrity": "sha512-W3Nh2cO7gMV91r+hLqyTMgKlvRl4W5diKs5YiyOxjZumRkMBy42IzcNYtgIIacOxghklv96F5Bd1Vx/zY6ylGA==", "dev": true, "dependencies": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" + "@cspell/cspell-pipe": "8.7.0", + "@cspell/cspell-types": "8.7.0", + "gensequence": "^7.0.0" + }, + "engines": { + "node": ">=18" } }, - "node_modules/each-props": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", - "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", + "node_modules/cspell/node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "dependencies": { - "is-plain-object": "^2.0.1", - "object.defaults": "^1.1.0" + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "node_modules/cspell/node_modules/flat-cache": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.0.tgz", + "integrity": "sha512-EryKbCE/wxpxKniQlyas6PY1I9vwtF3uCBweX+N8KYTCn3Y12RTGtQAJ/bd5pl7kxUAc8v/R3Ake/N17OZiFqA==", "dev": true, "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" + "flatted": "^3.2.9", + "keyv": "^4.5.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">=16" } }, - "node_modules/editions": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz", - "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==", + "node_modules/cspell/node_modules/gensequence": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/gensequence/-/gensequence-7.0.0.tgz", + "integrity": "sha512-47Frx13aZh01afHJTB3zTtKIlFI6vWY+MYCN9Qpew6i52rfKjnhCF/l1YlC8UmEMvvntZZ6z4PiCcmyuedR2aQ==", "dev": true, "engines": { - "node": ">=0.8" + "node": ">=18" } }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "node_modules/emittery": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", - "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", + "node_modules/cspell/node_modules/rimraf": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" + "url": "https://github.com/sponsors/isaacs" } }, - "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==", - "dev": true - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "node_modules/cspell/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, "engines": { - "node": ">= 0.8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "node_modules/cspell/node_modules/yaml": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", + "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==", "dev": true, - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" } }, - "node_modules/encoding/node_modules/iconv-lite": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", - "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", "dev": true, - "optional": true, "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/sponsors/fb55" } }, - "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==", + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", "dev": true, - "dependencies": { - "once": "^1.4.0" + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" } }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", "dev": true, "dependencies": { - "ansi-colors": "^4.1.1" + "assert-plus": "^1.0.0" }, "engines": { - "node": ">=8.6" + "node": ">=0.10" } }, - "node_modules/err-code": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", - "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=", + "node_modules/dataloader": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-2.2.2.tgz", + "integrity": "sha512-8YnDaaf7N3k/q5HnTJVuzSyLETjoZjVmHc4AeKAzOvKHEFQKcn64OKBfzHYtE9zGjctNM7V9I0MfnUVLpi7M5g==", "dev": true }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } + "node_modules/dayjs": { + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==", + "dev": true }, - "node_modules/es-abstract": { - "version": "1.18.0-next.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.2.tgz", - "integrity": "sha512-Ih4ZMFHEtZupnUh6497zEL4y2+w8+1ljnCyaTa+adcoafI1GOvMwFlDjBLfWR7y9VLfrjRJe9ocuHY1PSR9jjw==", + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.1", - "object-inspect": "^1.9.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.3", - "string.prototype.trimstart": "^1.0.3" + "ms": "2.1.2" }, "engines": { - "node": ">= 0.4" + "node": ">=6.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "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": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "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": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=4" } }, - "node_modules/es5-ext": { - "version": "0.10.53", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", - "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "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": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" + "file-type": "^5.2.0", + "is-stream": "^1.1.0", + "tar-stream": "^1.5.2" + }, + "engines": { + "node": ">=4" } }, - "node_modules/es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "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, - "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" + "engines": { + "node": ">=0.10.0" } }, - "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==", + "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": { - "d": "^1.0.1", - "ext": "^1.1.2" + "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/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==", + "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, - "dependencies": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" + "engines": { + "node": ">=4" } }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "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": ">=6" + "node": ">=0.10.0" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "node_modules/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": ">=0.8.0" + "node": ">=4" } }, - "node_modules/escaya": { - "version": "0.0.61", - "resolved": "https://registry.npmjs.org/escaya/-/escaya-0.0.61.tgz", - "integrity": "sha512-WLLmvdG72Z0pCq8XUBd03GEJlAiMceXFanjdQeEzeSiuV1ZgrJqbkU7ZEe/hu0OsBlg5wLlySEeOvfzcGoO8mg==", + "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": ">=6.0.0" + "node": ">=0.10.0" } }, - "node_modules/escodegen": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "node_modules/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": { - "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" + "file-type": "^3.8.0", + "get-stream": "^2.2.0", + "pify": "^2.3.0", + "yauzl": "^2.4.2" }, "engines": { - "node": ">=4.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" + "node": ">=4" } }, - "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==", + "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, - "optional": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/esm": { - "version": "3.2.25", - "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", - "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", + "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": ">=6" + "node": ">=0.10.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==", + "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, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "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.0" + "node": ">=4" } }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "node_modules/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": ">=0.10.0" + "node": ">=4" } }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "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.6" + "node": ">=0.10.0" } }, - "node_modules/eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", - "dev": true - }, - "node_modules/events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", + "node_modules/dedent": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", + "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", "dev": true, - "engines": { - "node": ">=0.8.x" + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } } }, - "node_modules/exec-sh": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", - "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", - "dev": true - }, - "node_modules/execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", "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" + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "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": ">= 0.8.0" + "node": ">=4.0.0" } }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "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==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, - "dependencies": { - "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" - }, "engines": { "node": ">=0.10.0" } }, - "node_modules/expand-brackets/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", "dev": true, "dependencies": { - "is-descriptor": "^0.1.0" + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, - "node_modules/expand-brackets/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "node_modules/define-properties": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", "dev": true, "dependencies": { - "is-extendable": "^0.1.0" + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/expand-brackets/node_modules/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=", + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "dev": true + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, "engines": { - "node": ">=0.10.0" + "node": ">=0.4.0" } }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, "engines": { - "node": ">=0.10.0" + "node": ">=0.10" } }, - "node_modules/expand-brackets/node_modules/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=", + "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==", "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8" } }, - "node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/destr": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.2.tgz", + "integrity": "sha512-65AlobnZMiCET00KaFFjUefxDX0khFA/E4myqZ7a6Sq1yZtR8+FVIvilVX66vF2uobSumxooYZChiRPCKNqhmg==", + "dev": true + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/expand-brackets/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "node_modules/detect-libc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/expand-brackets/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, - "dependencies": { - "homedir-polyfill": "^1.0.1" - }, "engines": { - "node": ">=0.10.0" + "node": ">=0.3.1" } }, - "node_modules/expect": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.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": { - "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" + "path-type": "^4.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=8" } }, - "node_modules/express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "dependencies": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" + "esutils": "^2.0.2" }, "engines": { - "node": ">= 0.10.0" + "node": ">=6.0.0" } }, - "node_modules/ext": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", - "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dev": true, "dependencies": { - "type": "^2.0.0" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "node_modules/ext/node_modules/type": { + "node_modules/domelementtype": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.3.0.tgz", - "integrity": "sha512-rgPIqOdfK/4J9FhiVrZ3cveAjRRo5rsQBAIhnylX874y1DX/kEKSVdLsnuHB6l1KTjHyU01VjiMBHgU2adejyg==", - "dev": true + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" + "domelementtype": "^2.3.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "dependencies": { - "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" + "node": ">= 4" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" } }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "dev": true, "dependencies": { - "is-descriptor": "^1.0.0" + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" } }, - "node_modules/extglob/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "node_modules/dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", "dev": true, "dependencies": { - "is-extendable": "^0.1.0" + "is-obj": "^2.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/extglob/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" } }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true, - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fancy-log": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", - "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", + "node_modules/dset": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.2.tgz", + "integrity": "sha512-g/M9sqy3oHe477Ar4voQxWtaPIFw1jTdKZuomOjhCcBx9nHUNn0pu6NopuFFrTh/TRZIKEj+76vLWFu9BNKk+Q==", "dev": true, - "dependencies": { - "ansi-gray": "^0.1.1", - "color-support": "^1.1.3", - "parse-node-version": "^1.0.0", - "time-stamp": "^1.0.0" - }, "engines": { - "node": ">= 0.10" + "node": ">=4" } }, - "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/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true }, - "node_modules/fast-glob": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", - "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "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==", "dev": true, "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", - "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8" + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.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/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==", "dev": true }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "node_modules/electron-to-chromium": { + "version": "1.4.454", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.454.tgz", + "integrity": "sha512-pmf1rbAStw8UEQ0sr2cdJtWl48ZMuPD9Sto8HVQOq9vx9j2WgDEN6lYoaqFvqEHYOmGA9oRGn7LqWI9ta0YugQ==", "dev": true }, - "node_modules/fastq": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.10.0.tgz", - "integrity": "sha512-NL2Qc5L3iQEsyYzweq7qfgy5OtXCmGzGvhElGEd/SoFWEMOEczNh5s5ocaF01HDetxz+p8ecjNPA6cZxxIHmzA==", + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true, - "dependencies": { - "reusify": "^1.0.4" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, - "node_modules/fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "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==", "dev": true, - "dependencies": { - "bser": "2.1.1" + "engines": { + "node": ">= 0.8" } }, - "node_modules/figlet": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.5.0.tgz", - "integrity": "sha512-ZQJM4aifMpz6H19AW1VqvZ7l4pOE9p7i/3LyxgO2kp+PO/VcDYNqIHEMtkccqIhTXMKci4kjueJr/iCQEaT/Ww==", + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "dev": true, - "engines": { - "node": ">= 0.4.0" + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" } }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, + "optional": true, "dependencies": { - "escape-string-regexp": "^1.0.5" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.10.0" } }, - "node_modules/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==", + "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==", "dev": true, - "optional": true + "dependencies": { + "once": "^1.4.0" + } }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "node_modules/enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", "dev": true, "dependencies": { - "to-regex-range": "^5.0.1" + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" }, "engines": { - "node": ">=8" + "node": ">=10.13.0" } }, - "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, "engines": { - "node": ">= 0.8" + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" + "is-arrayish": "^0.2.1" } }, - "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==", + "node_modules/es-abstract": { + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", + "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", "dev": true, "dependencies": { - "semver-regex": "^3.1.2" + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.2", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.5", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.2", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.12", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "safe-array-concat": "^1.0.1", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.13" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/findup-sync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", - "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "node_modules/es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", "dev": true, "dependencies": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" }, - "engines": { - "node": ">= 0.10" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/findup-sync/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "node_modules/es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", "dev": true, "dependencies": { - "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" + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, - "node_modules/findup-sync/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", "dev": true, "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" + "hasown": "^2.0.0" } }, - "node_modules/findup-sync/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/findup-sync/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "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/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/findup-sync/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "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==", + "dev": true + }, + "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==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/findup-sync/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "node_modules/eslint": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", "dev": true, "dependencies": { - "kind-of": "^3.0.2" + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.56.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "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.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "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.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "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.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" }, "engines": { - "node": ">=0.10.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/findup-sync/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/eslint-config-airbnb-base": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", + "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", "dev": true, "dependencies": { - "is-buffer": "^1.1.5" + "confusing-browser-globals": "^1.0.10", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5", + "semver": "^6.3.0" }, "engines": { - "node": ">=0.10.0" + "node": "^10.12.0 || >=12.0.0" + }, + "peerDependencies": { + "eslint": "^7.32.0 || ^8.2.0", + "eslint-plugin-import": "^2.25.2" } }, - "node_modules/findup-sync/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==", + "node_modules/eslint-config-airbnb-base/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, - "engines": { - "node": ">=0.10.0" + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/findup-sync/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "node_modules/eslint-config-airbnb-typescript": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-17.1.0.tgz", + "integrity": "sha512-GPxI5URre6dDpJ0CtcthSZVBAfI+Uw7un5OYNVxP2EYi3H81Jw701yFP7AU+/vCE7xBtFmjge7kfhhk4+RAiig==", "dev": true, "dependencies": { - "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" + "eslint-config-airbnb-base": "^15.0.0" }, - "engines": { - "node": ">=0.10.0" + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^5.13.0 || ^6.0.0", + "@typescript-eslint/parser": "^5.0.0 || ^6.0.0", + "eslint": "^7.32.0 || ^8.2.0", + "eslint-plugin-import": "^2.25.3" } }, - "node_modules/findup-sync/node_modules/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=", + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "bin": { + "eslint-config-prettier": "bin/cli.js" }, - "engines": { - "node": ">=0.10.0" + "peerDependencies": { + "eslint": ">=7.0.0" } }, - "node_modules/fined": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", - "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, "dependencies": { - "expand-tilde": "^2.0.2", - "is-plain-object": "^2.0.3", - "object.defaults": "^1.1.0", - "object.pick": "^1.2.0", - "parse-filepath": "^1.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/flagged-respawn": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", - "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", - "dev": true, - "engines": { - "node": ">= 0.10" + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" } }, - "node_modules/flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" + "ms": "^2.1.1" } }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "node_modules/eslint-import-resolver-typescript": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", + "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", "dev": true, "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true, + "debug": "^4.3.4", + "enhanced-resolve": "^5.12.0", + "eslint-module-utils": "^2.7.4", + "fast-glob": "^3.3.1", + "get-tsconfig": "^4.5.0", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3" + }, "engines": { - "node": ">=0.10.0" + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*" } }, - "node_modules/for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "node_modules/eslint-module-utils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", "dev": true, "dependencies": { - "for-in": "^1.0.1" + "debug": "^3.2.7" }, "engines": { - "node": ">=0.10.0" + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "engines": { - "node": "*" + "dependencies": { + "ms": "^2.1.1" } }, - "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "node_modules/eslint-plugin-import": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" }, "engines": { - "node": ">= 6" + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" } }, - "node_modules/forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "engines": { - "node": ">= 0.6" + "dependencies": { + "ms": "^2.1.1" } }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "dependencies": { - "map-cache": "^0.2.2" + "esutils": "^2.0.2" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "node_modules/eslint-plugin-import/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, - "engines": { - "node": ">= 0.6" + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" } }, - "node_modules/fs-capacitor": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/fs-capacitor/-/fs-capacitor-2.0.4.tgz", - "integrity": "sha512-8S4f4WsCryNw2mJJchi46YgB6CR5Ze+4L1h8ewl9tEpL4SJ3ZO+c/bS4BWhB8bK+O3TMqhuZarTitd0S0eh2pA==", + "node_modules/eslint-plugin-import/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, - "engines": { - "node": ">=8.5" + "bin": { + "semver": "bin/semver.js" } }, - "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==", + "node_modules/eslint-plugin-import/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, - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, "engines": { - "node": ">=10" + "node": ">=4" } }, - "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==", + "node_modules/eslint-plugin-import/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": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" } }, - "node_modules/fs-mkdirp-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", - "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", + "node_modules/eslint-plugin-jest": { + "version": "27.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.6.2.tgz", + "integrity": "sha512-CI1AlKrsNhYFoP48VU8BVWOi7+qHTq4bRxyUlGjeU8SfFt8abjXhjOuDzUoMp68DoXIx17KpNpIkMrl4s4ZW0g==", "dev": true, "dependencies": { - "graceful-fs": "^4.1.11", - "through2": "^2.0.3" + "@typescript-eslint/utils": "^5.10.0" }, "engines": { - "node": ">= 0.10" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^5.0.0 || ^6.0.0", + "eslint": "^7.0.0 || ^8.0.0", + "jest": "*" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } } }, - "node_modules/fs-mkdirp-stream/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "node_modules/eslint-plugin-tsdoc": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/eslint-plugin-tsdoc/-/eslint-plugin-tsdoc-0.2.17.tgz", + "integrity": "sha512-xRmVi7Zx44lOBuYqG8vzTXuL6IdGOeF9nHX17bjJ8+VE6fsxpdGem0/SBTmAwgYMKYB1WBkqRJVQ+n8GK041pA==", "dev": true, "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" + "@microsoft/tsdoc": "0.14.2", + "@microsoft/tsdoc-config": "0.16.2" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=8.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==", - "dev": true - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "node_modules/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": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "node_modules/get-intrinsic": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.2.tgz", - "integrity": "sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "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" + "url": "https://opencollective.com/eslint" } }, - "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==", + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { - "pump": "^3.0.0" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">=8" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/eslint" } }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=4.0" } }, - "node_modules/getopts": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.2.5.tgz", - "integrity": "sha512-9jb7AW5p3in+IiJWhQiZmmwkpLaR/ccTWdWQCtZM66HJcHHLegowh4q4tSD7gouUyeNvFWRavfK9GXosQHDpFA==", - "dev": true - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "node_modules/esm": { + "version": "3.2.25", + "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", + "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" + "engines": { + "node": ">=6" } }, - "node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, "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" + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": "*" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://opencollective.com/eslint" } }, - "node_modules/glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "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, - "dependencies": { - "is-glob": "^4.0.1" + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" }, "engines": { - "node": ">= 6" + "node": ">=4" } }, - "node_modules/glob-stream": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", - "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "dependencies": { - "extend": "^3.0.0", - "glob": "^7.1.1", - "glob-parent": "^3.1.0", - "is-negated-glob": "^1.0.0", - "ordered-read-streams": "^1.0.0", - "pumpify": "^1.3.5", - "readable-stream": "^2.1.5", - "remove-trailing-separator": "^1.0.1", - "to-absolute-glob": "^2.0.0", - "unique-stream": "^2.0.2" + "estraverse": "^5.1.0" }, "engines": { - "node": ">= 0.10" + "node": ">=0.10" } }, - "node_modules/glob-stream/node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" + "engines": { + "node": ">=4.0" } }, - "node_modules/glob-stream/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "dependencies": { - "is-extglob": "^2.1.0" + "estraverse": "^5.2.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=4.0" } }, - "node_modules/glob-watcher": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.5.tgz", - "integrity": "sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw==", + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "dependencies": { - "anymatch": "^2.0.0", - "async-done": "^1.2.0", - "chokidar": "^2.0.0", - "is-negated-glob": "^1.0.0", - "just-debounce": "^1.0.0", - "normalize-path": "^3.0.0", - "object.defaults": "^1.1.0" - }, "engines": { - "node": ">= 0.10" + "node": ">=4.0" } }, - "node_modules/glob-watcher/node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" + "engines": { + "node": ">=4.0" } }, - "node_modules/glob-watcher/node_modules/anymatch/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" + "@types/estree": "^1.0.0" } }, - "node_modules/glob-watcher/node_modules/binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/glob-watcher/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, - "dependencies": { - "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" - }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.6" } }, - "node_modules/glob-watcher/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "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": { - "is-extendable": "^0.1.0" + "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": ">=0.10.0" - } - }, - "node_modules/glob-watcher/node_modules/chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.", - "dev": true, - "dependencies": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "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" + "node": ">=10" }, - "optionalDependencies": { - "fsevents": "^1.2.7" + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/glob-watcher/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "node_modules/execa/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/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8.0" } }, - "node_modules/glob-watcher/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", "dev": true, "dependencies": { - "is-extendable": "^0.1.0" + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { - "node": ">=0.10.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/glob-watcher/node_modules/fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.12.1" + "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": ">= 4.0" + "node": ">= 0.10.0" } }, - "node_modules/glob-watcher/node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "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==", "dev": true, "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/glob-watcher/node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "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==", "dev": true, "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" + "ms": "2.0.0" } }, - "node_modules/glob-watcher/node_modules/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=", + "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==", + "dev": true + }, + "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==", "dev": true, "dependencies": { - "binary-extensions": "^1.0.0" + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8" } }, - "node_modules/glob-watcher/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", "dev": true, - "engines": { - "node": ">=0.10.0" - } + "engines": [ + "node >=0.6.0" + ] }, - "node_modules/glob-watcher/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "node_modules/fast-decode-uri-component": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", + "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==", + "dev": true + }, + "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==", + "dev": true + }, + "node_modules/fast-equals": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz", + "integrity": "sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==", "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, "engines": { - "node": ">=0.10.0" + "node": ">=6.0.0" } }, - "node_modules/glob-watcher/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "dependencies": { - "is-buffer": "^1.1.5" + "@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": ">=0.10.0" + "node": ">=8.6.0" } }, - "node_modules/glob-watcher/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "node_modules/fast-glob/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": { - "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" + "is-glob": "^4.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 6" } }, - "node_modules/glob-watcher/node_modules/micromatch/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==", + "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==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fast-querystring": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", + "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "fast-decode-uri-component": "^1.0.1" } }, - "node_modules/glob-watcher/node_modules/readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "node_modules/fast-url-parser": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", + "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", "dev": true, "dependencies": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "engines": { - "node": ">=0.10" + "punycode": "^1.3.2" } }, - "node_modules/glob-watcher/node_modules/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=", + "node_modules/fast-url-parser/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==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" + "reusify": "^1.0.4" } }, - "node_modules/global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, "dependencies": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" + "bser": "2.1.1" } }, - "node_modules/global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "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": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - }, - "engines": { - "node": ">=0.10.0" + "pend": "~1.2.0" } }, - "node_modules/global-prefix/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "dependencies": { - "isexe": "^2.0.0" + "flat-cache": "^3.0.4" }, - "bin": { - "which": "bin/which" + "engines": { + "node": "^10.12.0 || >=12.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==", + "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/globby": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.2.tgz", - "integrity": "sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og==", + "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": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" + "to-regex-range": "^5.0.1" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/glogg": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", - "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dev": true, "dependencies": { - "sparkles": "^1.0.0" + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" }, "engines": { - "node": ">= 0.10" + "node": ">= 0.8" } }, - "node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "node_modules/graphql": { - "version": "15.5.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.5.0.tgz", - "integrity": "sha512-OmaM7y0kaK31NKG31q4YbD2beNYa6jBBKtMFT6gLYJljHLJr42IqJ8KX08u3Li/0ifzTU5HjmoOOrwa5BRLeDA==", - "engines": { - "node": ">= 10.x" + "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==", + "dev": true, + "dependencies": { + "ms": "2.0.0" } }, - "node_modules/graphql-extensions": { - "version": "0.12.8", - "resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.12.8.tgz", - "integrity": "sha512-xjsSaB6yKt9jarFNNdivl2VOx52WySYhxPgf8Y16g6GKZyAzBoIFiwyGw5PJDlOSUa6cpmzn6o7z8fVMbSAbkg==", + "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==", + "dev": true + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "dependencies": { - "@apollographql/apollo-tools": "^0.4.3", - "apollo-server-env": "^3.0.0", - "apollo-server-types": "^0.6.3" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=6.0" + "node": ">=10" }, - "peerDependencies": { - "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/graphql-query-complexity": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/graphql-query-complexity/-/graphql-query-complexity-0.7.2.tgz", - "integrity": "sha512-+VgmrfxGEjHI3zuojWOR8bsz7Ycz/BZjNjxnlUieTz5DsB92WoIrYCSZdWG7UWZ3rfcA1Gb2Nf+wB80GsaZWuQ==", - "dependencies": { - "lodash.get": "^4.4.2" + "node_modules/find-up-simple": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.0.tgz", + "integrity": "sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==", + "dev": true, + "engines": { + "node": ">=18" }, - "peerDependencies": { - "graphql": "^0.13.0 || ^14.0.0 || ^15.0.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/graphql-redis-subscriptions": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/graphql-redis-subscriptions/-/graphql-redis-subscriptions-2.3.1.tgz", - "integrity": "sha512-ztS3ZXBSoPJ8Q0/o7PG2iLO6QWq2tlJrukiBJCjgMccRv1I3lt3HmLjiH2CbDjPhpoINttZNoytQbxE0OE/UpA==", + "node_modules/flat-cache": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz", + "integrity": "sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==", "dev": true, "dependencies": { - "iterall": "^1.3.0" - }, - "optionalDependencies": { - "ioredis": "^4.17.3" + "flatted": "^3.2.7", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" }, - "peerDependencies": { - "graphql-subscriptions": "^1.0.0" + "engines": { + "node": ">=12.0.0" } }, - "node_modules/graphql-subscriptions": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-1.2.0.tgz", - "integrity": "sha512-uXvp729fztqwa7HFUFaAqKwNMwwOfsvu4HwOu7/35Cd44bNrMPCn97mNGN0ybuuZE36CPXBTaW/4U/xyOS4D9w==", + "node_modules/flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, "dependencies": { - "iterall": "^1.3.0" - }, - "peerDependencies": { - "graphql": "^0.10.5 || ^0.11.3 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "is-callable": "^1.1.3" } }, - "node_modules/graphql-tag": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.11.0.tgz", - "integrity": "sha512-VmsD5pJqWJnQZMUeRwrDhfgoyqcfwEkvtpANqcoUG8/tOLkwNgU9mzub/Mc78OJMhHjx7gfAMTxzdG43VGg3bA==", + "node_modules/for-each-property": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/for-each-property/-/for-each-property-0.0.4.tgz", + "integrity": "sha512-xYs28PM0CKXETFzuGC6ZooH0voZlsSDZwidJcy92flQJi3PK7i3gZx23xHXCPOaD4zmet3bDo+wS7E7SujrlCw==", "dev": true, - "peerDependencies": { - "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "dependencies": { + "get-prototype-chain": "^1.0.1" } }, - "node_modules/graphql-tools": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-4.0.8.tgz", - "integrity": "sha512-MW+ioleBrwhRjalKjYaLQbr+920pHBgy9vM/n47sswtns8+96sRn5M/G+J1eu7IMeKWiN/9p6tmwCHU7552VJg==", + "node_modules/for-each-property-deep": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/for-each-property-deep/-/for-each-property-deep-0.0.3.tgz", + "integrity": "sha512-qzP8QkODWVVRPpWiBZacSbBl67cTTWoBfxMG0wE46AsS1yl7qv05sGN+dHvD4s4tnvl/goe6Sp4qBI+rlVBgNg==", "dev": true, "dependencies": { - "apollo-link": "^1.2.14", - "apollo-utilities": "^1.0.1", - "deprecated-decorator": "^0.1.6", - "iterall": "^1.1.3", - "uuid": "^3.1.0" - }, - "peerDependencies": { - "graphql": "^0.13.0 || ^14.0.0 || ^15.0.0" + "for-each-property": "0.0.4" } }, - "node_modules/graphql-tools/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", "dev": true, - "bin": { - "uuid": "bin/uuid" + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "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==", "dev": true, - "optional": true + "engines": { + "node": "*" + } }, - "node_modules/gulp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", - "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", + "node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", "dev": true, "dependencies": { - "glob-watcher": "^5.0.3", - "gulp-cli": "^2.2.0", - "undertaker": "^1.2.1", - "vinyl-fs": "^3.0.0" - }, - "bin": { - "gulp": "bin/gulp.js" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" }, "engines": { - "node": ">= 0.10" + "node": ">= 6" } }, - "node_modules/gulp-cli": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz", - "integrity": "sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==", - "dev": true, - "dependencies": { - "ansi-colors": "^1.0.1", - "archy": "^1.0.0", - "array-sort": "^1.0.0", - "color-support": "^1.1.3", - "concat-stream": "^1.6.0", - "copy-props": "^2.0.1", - "fancy-log": "^1.3.2", - "gulplog": "^1.0.0", - "interpret": "^1.4.0", - "isobject": "^3.0.1", - "liftoff": "^3.1.0", - "matchdep": "^2.0.0", - "mute-stdout": "^1.0.0", - "pretty-hrtime": "^1.0.0", - "replace-homedir": "^1.0.0", - "semver-greatest-satisfied-range": "^1.1.0", - "v8flags": "^3.2.0", - "yargs": "^7.1.0" - }, - "bin": { - "gulp": "bin/gulp.js" - }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, "engines": { - "node": ">= 0.10" + "node": ">= 0.6" } }, - "node_modules/gulp-cli/node_modules/ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true, - "dependencies": { - "ansi-wrap": "^0.1.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.6" } }, - "node_modules/gulp-replace": { + "node_modules/fs-constants": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulp-replace/-/gulp-replace-1.0.0.tgz", - "integrity": "sha512-lgdmrFSI1SdhNMXZQbrC75MOl1UjYWlOWNbNRnz+F/KHmgxt3l6XstBoAYIdadwETFyG/6i+vWUSCawdC3pqOw==", + "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": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, "dependencies": { - "istextorbinary": "2.2.1", - "readable-stream": "^2.0.1", - "replacestream": "^4.0.0" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": ">=0.10" + "node": ">=14.14" } }, - "node_modules/gulp-shell": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/gulp-shell/-/gulp-shell-0.8.0.tgz", - "integrity": "sha512-wHNCgmqbWkk1c6Gc2dOL5SprcoeujQdeepICwfQRo91DIylTE7a794VEE+leq3cE2YDoiS5ulvRfKVIEMazcTQ==", + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", "dev": true, "dependencies": { - "chalk": "^3.0.0", - "fancy-log": "^1.3.3", - "lodash.template": "^4.5.0", - "plugin-error": "^1.0.1", - "through2": "^3.0.1", - "tslib": "^1.10.0" + "minipass": "^7.0.3" }, "engines": { - "node": ">=10.0.0" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/gulp-shell/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, - "node_modules/gulp-typescript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/gulp-typescript/-/gulp-typescript-5.0.1.tgz", - "integrity": "sha512-YuMMlylyJtUSHG1/wuSVTrZp60k1dMEFKYOvDf7OvbAJWrDtxxD4oZon4ancdWwzjj30ztiidhe4VXJniF0pIQ==", + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, "dependencies": { - "ansi-colors": "^3.0.5", - "plugin-error": "^1.0.1", - "source-map": "^0.7.3", - "through2": "^3.0.0", - "vinyl": "^2.1.0", - "vinyl-fs": "^3.0.3" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" }, "engines": { - "node": ">= 8" + "node": ">= 0.4" }, - "peerDependencies": { - "typescript": "~2.7.1 || >=2.8.0-dev || >=2.9.0-dev || ~3.0.0 || >=3.0.0-dev || >=3.1.0-dev || >= 3.2.0-dev || >= 3.3.0-dev" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gulp-typescript/node_modules/ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, - "engines": { - "node": ">=6" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gulpclass": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/gulpclass/-/gulpclass-0.2.0.tgz", - "integrity": "sha512-S2p0SgnVLjBbIEw5tHbBV6Wm6abD+leA5xZG6ukf9M+j1I/8zIeKPby9GLWnI90671YRk+lXbvEUROKaZXo8NA==", + "node_modules/gensequence": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gensequence/-/gensequence-6.0.0.tgz", + "integrity": "sha512-8WwuywE9pokJRAcg2QFR/plk3cVPebSUqRPzpGQh3WQ0wIiHAw+HyOQj5IuHyUTQBHpBKFoB2JUMu9zT3vJ16Q==", "dev": true, - "dependencies": { - "@types/gulp": "^4.0.5", - "@types/merge2": "^1.1.4", - "@types/node": "*", - "gulp": "^4.0.0", - "merge2": "^1.2.2" + "engines": { + "node": ">=16" } }, - "node_modules/gulplog": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", - "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, - "dependencies": { - "glogg": "^1.0.0" - }, "engines": { - "node": ">= 0.10" + "node": ">=6.9.0" } }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "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==", "dev": true, "engines": { - "node": ">=4" + "node": "6.* || 8.* || >= 10.*" } }, - "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", + "node_modules/get-east-asian-width": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", + "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", "dev": true, - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, "engines": { - "node": ">=6" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", "dev": true, "dependencies": { - "function-bind": "^1.1.1" + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" }, - "engines": { - "node": ">= 0.4.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "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, - "dependencies": { - "ansi-regex": "^2.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=8.0.0" } }, - "node_modules/has-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "node_modules/get-prototype-chain": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-prototype-chain/-/get-prototype-chain-1.0.1.tgz", + "integrity": "sha512-2m7WZ0jveIg/dAbCbpUxEToaJ8Dmti5EkgDP8YM3UpHUT6SAORjE2odP8XQGNVGXMHi8q8cCCoy3HTByTaTVTw==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=4.0.0" } }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/get-stdin": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", + "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", "dev": true, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "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": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/has-value": { + "node_modules/get-symbol-description": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", "dev": true, "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/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=", + "node_modules/get-tsconfig": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.6.2.tgz", + "integrity": "sha512-E5XrT4CbbXcXWy+1jChlZmrmCwd5KGx502kDCXJJ7y898TtWW9FwoG5HfOLVRKmlmDGkWN2HM9Ho+/Y8F0sJDg==", "dev": true, "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" + "resolve-pkg-maps": "^1.0.0" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, - "node_modules/has-values/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "node_modules/getopts": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.3.0.tgz", + "integrity": "sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==", + "dev": true + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", "dev": true, "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" + "assert-plus": "^1.0.0" } }, - "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", "dev": true, "dependencies": { - "is-buffer": "^1.1.5" + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": ">=0.10.0" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "dependencies": { - "is-buffer": "^1.1.5" + "is-glob": "^4.0.3" }, "engines": { - "node": ">=0.10.0" + "node": ">=10.13.0" } }, - "node_modules/highlight.js": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.6.0.tgz", - "integrity": "sha512-8mlRcn5vk/r4+QcqerapwBYTe+iPL5ih6xrNylxrnBdHQiijDETfXX7VIxC3UiCRiINBJfANBAsPzAvRQj8RpQ==", + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "engines": { - "node": "*" + "dependencies": { + "balanced-match": "^1.0.0" } }, - "node_modules/homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, "dependencies": { - "parse-passwd": "^1.0.0" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", - "dev": true - }, - "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "node_modules/global-agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", + "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", "dev": true, "dependencies": { - "whatwg-encoding": "^1.0.5" + "boolean": "^3.0.1", + "es6-error": "^4.1.1", + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" }, "engines": { - "node": ">=10" + "node": ">=10.0" } }, - "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/http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, - "node_modules/http-errors": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", - "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "node_modules/global-directory": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", + "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", "dev": true, "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" + "ini": "4.1.1" }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "node_modules/global-directory/node_modules/ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", "dev": true, - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, "engines": { - "node": ">= 6" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/http-proxy-agent/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", "dev": true, "dependencies": { - "ms": "2.1.2" + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=6" } }, - "node_modules/http-proxy-agent/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "type-fest": "^0.20.2" }, "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "dev": true, "dependencies": { - "agent-base": "6", - "debug": "4" + "define-properties": "^1.1.3" }, "engines": { - "node": ">= 6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/https-proxy-agent/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "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": { - "ms": "2.1.2" + "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": ">=6.0" + "node": ">=10" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/https-proxy-agent/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, - "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, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/graphql": { + "version": "16.8.1", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.1.tgz", + "integrity": "sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==", "engines": { - "node": ">=8.12.0" + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } }, - "node_modules/humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", - "dev": true, + "node_modules/graphql-query-complexity": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/graphql-query-complexity/-/graphql-query-complexity-0.12.0.tgz", + "integrity": "sha512-fWEyuSL6g/+nSiIRgIipfI6UXTI7bAxrpPlCY1c0+V3pAEUo1ybaKmSBgNr1ed2r+agm1plJww8Loig9y6s2dw==", "dependencies": { - "ms": "^2.0.0" + "lodash.get": "^4.4.2" + }, + "peerDependencies": { + "graphql": "^14.6.0 || ^15.0.0 || ^16.0.0" } }, - "node_modules/husky": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.8.tgz", - "integrity": "sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==", + "node_modules/graphql-scalars": { + "version": "1.22.4", + "resolved": "https://registry.npmjs.org/graphql-scalars/-/graphql-scalars-1.22.4.tgz", + "integrity": "sha512-ILnv7jq5VKHLUyoaTFX7lgYrjCd6vTee9i8/B+D4zJKJT5TguOl0KkpPEbXHjmeor8AZYrVsrYUHdqRBMX1pjA==", "dev": true, - "hasInstallScript": true, "dependencies": { - "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" - }, - "bin": { - "husky-run": "bin/run.js", - "husky-upgrade": "lib/upgrader/bin.js" + "tslib": "^2.5.0" }, "engines": { "node": ">=10" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/husky" + "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/husky/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "node_modules/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": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "tslib": "^2.1.0" }, "engines": { "node": ">=10" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "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/husky/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==", + "node_modules/graphql-yoga": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/graphql-yoga/-/graphql-yoga-5.1.1.tgz", + "integrity": "sha512-oak5nVKTHpqJgpA1aT3cJPOlCidrW7l6nbc5L6w07VdFul16ielGI2ZnQDAXO+qQih09/4WspD5x0SsSZH+hkg==", "dev": true, "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" + "@envelop/core": "^5.0.0", + "@graphql-tools/executor": "^1.0.0", + "@graphql-tools/schema": "^10.0.0", + "@graphql-tools/utils": "^10.0.0", + "@graphql-yoga/logger": "^2.0.0", + "@graphql-yoga/subscription": "^5.0.0", + "@whatwg-node/fetch": "^0.9.7", + "@whatwg-node/server": "^0.9.1", + "dset": "^3.1.1", + "lru-cache": "^10.0.0", + "tslib": "^2.5.2" }, "engines": { - "node": ">=10" + "node": ">=18.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "graphql": "^15.2.0 || ^16.0.0" } }, - "node_modules/husky/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==", + "node_modules/graphql-yoga/node_modules/lru-cache": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", + "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "14 || >=16.14" } }, - "node_modules/husky/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==", + "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==", + "dev": true, + "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", "dev": true, "dependencies": { - "yocto-queue": "^0.1.0" + "ajv": "^6.12.3", + "har-schema": "^2.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=6" } }, - "node_modules/husky/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==", + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, "dependencies": { - "p-limit": "^3.0.2" + "function-bind": "^1.1.1" }, "engines": { - "node": ">=10" - }, + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/husky/node_modules/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==", + "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, - "dependencies": { - "find-up": "^5.0.0" - }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/has-own-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", "dev": true, "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "get-intrinsic": "^1.1.1" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", "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" - } - ] + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "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==", "dev": true, "engines": { - "node": ">= 4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "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==", + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", "dev": true, "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "has-symbols": "^1.0.2" }, "engines": { - "node": ">=6" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", "dev": true, "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" + "function-bind": "^1.1.2" }, "engines": { - "node": ">=8" + "node": ">= 0.4" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "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, - "engines": { - "node": ">=0.8.19" + "bin": { + "he": "bin/he" } }, - "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==", + "node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", "dev": true, "engines": { - "node": ">=8" + "node": "*" } }, - "node_modules/infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "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/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "node_modules/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/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "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/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "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==", "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, "engines": { - "node": ">= 0.10" + "node": ">= 0.8" } }, - "node_modules/invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "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==", "dev": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 6" } }, - "node_modules/ioredis": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.23.0.tgz", - "integrity": "sha512-R5TDCODwnEH3J3A5TSoB17+6a+SeJTtIOW6vsy5Q1yag/AM8FejHjZC5R2O1QepSXV8hwOnGSm/4buJc/LeXTQ==", + "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==", "dev": true, "dependencies": { - "cluster-key-slot": "^1.1.0", - "debug": "^4.1.1", - "denque": "^1.1.0", - "lodash.defaults": "^4.2.0", - "lodash.flatten": "^4.4.0", - "p-map": "^2.1.0", - "redis-commands": "1.7.0", - "redis-errors": "^1.2.0", - "redis-parser": "^3.0.0", - "standard-as-callback": "^2.0.1" + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/ioredis" + "node": ">=0.8", + "npm": ">=1.3.7" } }, - "node_modules/ioredis/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "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==", "dev": true, "dependencies": { - "ms": "2.1.2" + "agent-base": "6", + "debug": "4" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">= 6" } }, - "node_modules/ioredis/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/ioredis/node_modules/p-map": { + "node_modules/human-signals": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, "engines": { - "node": ">=6" + "node": ">=10.17.0" } }, - "node_modules/ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - }, - "node_modules/ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", "dev": true, - "engines": { - "node": ">=4" + "dependencies": { + "ms": "^2.0.0" } }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "node_modules/husky": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", + "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", "dev": true, + "bin": { + "husky": "lib/bin.js" + }, "engines": { - "node": ">= 0.10" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" } }, - "node_modules/is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "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==", "dev": true, "dependencies": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" + "safer-buffer": ">= 2.1.2 < 3" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/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==", + "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, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } + "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/is-accessor-descriptor/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==", + "node_modules/ignore": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">= 4" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "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==", + "node_modules/image-data-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/image-data-uri/-/image-data-uri-2.0.1.tgz", + "integrity": "sha512-BZh721F2Q5TwBdwpiqrBrHEdj8daj8KuMZK/DOCyqQlz1CqFhhuZWbK5ZCUnAvFJr8LaKHTaWl9ja3/a3DC2Ew==", "dev": true, "dependencies": { - "binary-extensions": "^2.0.0" + "fs-extra": "^0.26.7", + "magicli": "0.0.8", + "mime-types": "^2.1.18", + "request": "^2.88.0" }, - "engines": { - "node": ">=8" + "bin": { + "image-data-uri": "bin/magicli.js" } }, - "node_modules/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 + "node_modules/image-data-uri/node_modules/fs-extra": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", + "integrity": "sha512-waKu+1KumRhYv8D8gMRCKJGAMI9pRnPuEb1mvgYD0f7wBscg+h6bW4FDTmEZhB9VKxvoTtxW+Y7bnIlB7zja6Q==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } }, - "node_modules/is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "node_modules/image-data-uri/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, + "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": ">= 0.4" + "node": "*" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "node_modules/image-data-uri/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, - "dependencies": { - "ci-info": "^2.0.0" - }, - "bin": { - "is-ci": "bin.js" + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node_modules/is-core-module": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", - "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "node_modules/image-data-uri/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": { - "has": "^1.0.3" + "glob": "^7.1.3" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "bin": { + "rimraf": "bin.js" } }, - "node_modules/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==", + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "dependencies": { - "kind-of": "^6.0.0" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-data-descriptor/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/is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true, - "engines": { - "node": ">= 0.4" + "node": ">=6" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "node_modules/import-fresh/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==", "dev": true, "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "callsites": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/is-descriptor/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==", + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/is-docker": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", - "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==", + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, - "optional": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, "bin": { - "is-docker": "cli.js" + "import-local-fixture": "fixtures/cli.js" }, "engines": { "node": ">=8" @@ -7378,224 +8689,275 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/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==", + "node_modules/import-meta-resolve": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.0.0.tgz", + "integrity": "sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==", "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=0.8.19" } }, - "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==", + "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/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, - "engines": { - "node": ">=6" + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" } }, - "node_modules/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==", + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "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/inspect-function": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/inspect-function/-/inspect-function-0.3.4.tgz", + "integrity": "sha512-s0RsbJqK/sNZ+U1mykGoTickog3ea1A9Qk4mXniogOBu4PgkkZ56elScO7QC/r8D94lhGmJ2NyDI1ipOA/uq/g==", "dev": true, "dependencies": { - "is-extglob": "^2.1.1" + "inspect-parameters-declaration": "0.0.8", + "magicli": "0.0.8", + "split-skip": "0.0.1", + "stringify-parameters": "0.0.4", + "unpack-string": "0.0.2" }, - "engines": { - "node": ">=0.10.0" + "bin": { + "inspect-function": "bin/magicli.js" } }, - "node_modules/is-invalid-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-invalid-path/-/is-invalid-path-0.1.0.tgz", - "integrity": "sha1-MHqFWzzxqTi0TqcNLGEQYFNxTzQ=", + "node_modules/inspect-function/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/inspect-function/node_modules/get-stdin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", + "integrity": "sha512-jZV7n6jGE3Gt7fgSTJoz91Ak5MuTLwMwkoYdjxuJ/AmjIsE1UC03y/IWkZCQGEvVNS9qoRNwy5BCqxImv0FVeA==", "dev": true, - "dependencies": { - "is-glob": "^2.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=0.12.0" } }, - "node_modules/is-invalid-path/node_modules/is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "node_modules/inspect-function/node_modules/inspect-function": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/inspect-function/-/inspect-function-0.2.2.tgz", + "integrity": "sha512-becs5gzcHwPrlHawscYkyQ/ShiOiosrXPhA5RVZ3qyWH4aWdD52RnMfXq/dwQXciHwiieD8aIPwdIWYv6eL+sQ==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "split-skip": "0.0.1", + "unpack-string": "0.0.2" } }, - "node_modules/is-invalid-path/node_modules/is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "node_modules/inspect-function/node_modules/inspect-parameters-declaration": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/inspect-parameters-declaration/-/inspect-parameters-declaration-0.0.8.tgz", + "integrity": "sha512-W4QzN1LgFmasKOM+NoLlDd2OAZM3enNZlVUOXoGQKmYBDFgxoPDOyebF55ALaf8avyM9TavNwibXxg347RrzCg==", "dev": true, "dependencies": { - "is-extglob": "^1.0.0" + "magicli": "0.0.5", + "split-skip": "0.0.2", + "stringify-parameters": "0.0.4", + "unpack-string": "0.0.2" }, - "engines": { - "node": ">=0.10.0" + "bin": { + "inspect-parameters-declaration": "bin/cli.js" } }, - "node_modules/is-lambda": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=", - "dev": true - }, - "node_modules/is-negated-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", - "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", + "node_modules/inspect-function/node_modules/inspect-parameters-declaration/node_modules/magicli": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/magicli/-/magicli-0.0.5.tgz", + "integrity": "sha512-wZbMtnl2v1b+Jp3xlqA9FU/O4I6YhGXR8xSY/eU2+gDAvut/F+W3gl4qs61iL4LELC7jqSAE6aAD5668EbmQHA==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "commander": "^2.9.0", + "get-stdin": "^5.0.1", + "inspect-function": "^0.2.1", + "pipe-functions": "^1.2.0" } }, - "node_modules/is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "node_modules/inspect-function/node_modules/inspect-parameters-declaration/node_modules/split-skip": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/split-skip/-/split-skip-0.0.2.tgz", + "integrity": "sha512-weHOi8BolsDnGIwhhWHbA+wKSuSpvWwjRrdj8SdbIIis2vSwOE37CQP8x3EleuzxanUr3AK8BdUy4MkiOULPZg==", + "dev": true + }, + "node_modules/inspect-function/node_modules/split-skip": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/split-skip/-/split-skip-0.0.1.tgz", + "integrity": "sha512-7dkvq+gofI4M8zx4iZnEZ3O1s7FP4Y/iaIDHJh5RyWrs8idcPauFi2OZe3TBi36fLvR2j5z3kSzVtz6IhPdncQ==", + "dev": true + }, + "node_modules/inspect-parameters-declaration": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/inspect-parameters-declaration/-/inspect-parameters-declaration-0.0.9.tgz", + "integrity": "sha512-c3jrKKA1rwwrsjdGMAo2hFWV0vNe3/RKHxpE/OBt41LP3ynOVI1qmgxpZYK5SQu3jtWCyaho8L7AZzCjJ4mEUw==", "dev": true, - "engines": { - "node": ">= 0.4" + "dependencies": { + "magicli": "0.0.5", + "split-skip": "0.0.2", + "stringify-parameters": "0.0.4", + "unpack-string": "0.0.2" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "bin": { + "inspect-parameters-declaration": "bin/cli.js" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/inspect-parameters-declaration/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/inspect-parameters-declaration/node_modules/get-stdin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", + "integrity": "sha512-jZV7n6jGE3Gt7fgSTJoz91Ak5MuTLwMwkoYdjxuJ/AmjIsE1UC03y/IWkZCQGEvVNS9qoRNwy5BCqxImv0FVeA==", "dev": true, "engines": { "node": ">=0.12.0" } }, - "node_modules/is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "node_modules/inspect-parameters-declaration/node_modules/inspect-function": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/inspect-function/-/inspect-function-0.2.2.tgz", + "integrity": "sha512-becs5gzcHwPrlHawscYkyQ/ShiOiosrXPhA5RVZ3qyWH4aWdD52RnMfXq/dwQXciHwiieD8aIPwdIWYv6eL+sQ==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "split-skip": "0.0.1", + "unpack-string": "0.0.2" } }, - "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/inspect-parameters-declaration/node_modules/inspect-function/node_modules/split-skip": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/split-skip/-/split-skip-0.0.1.tgz", + "integrity": "sha512-7dkvq+gofI4M8zx4iZnEZ3O1s7FP4Y/iaIDHJh5RyWrs8idcPauFi2OZe3TBi36fLvR2j5z3kSzVtz6IhPdncQ==", + "dev": true }, - "node_modules/is-path-inside": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", - "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", + "node_modules/inspect-parameters-declaration/node_modules/magicli": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/magicli/-/magicli-0.0.5.tgz", + "integrity": "sha512-wZbMtnl2v1b+Jp3xlqA9FU/O4I6YhGXR8xSY/eU2+gDAvut/F+W3gl4qs61iL4LELC7jqSAE6aAD5668EbmQHA==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "commander": "^2.9.0", + "get-stdin": "^5.0.1", + "inspect-function": "^0.2.1", + "pipe-functions": "^1.2.0" } }, - "node_modules/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==", + "node_modules/inspect-property": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/inspect-property/-/inspect-property-0.0.6.tgz", + "integrity": "sha512-LgjHkRl9W6bj2n+kWrAOgvCYPTYt+LanE4rtd/vKNq6yEb+SvVV7UTLzoSPpDX6/U1cAz7VfqPr+lPAIz7wHaQ==", "dev": true, "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" + "for-each-property": "0.0.4", + "for-each-property-deep": "0.0.3", + "inspect-function": "^0.3.1" } }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", - "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", - "dev": true - }, - "node_modules/is-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", - "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", + "node_modules/internal-slot": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.1" + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "node_modules/interpret": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">= 0.10" } }, - "node_modules/is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "node_modules/ioredis": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.3.2.tgz", + "integrity": "sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA==", "dev": true, "dependencies": { - "is-unc-path": "^1.0.0" + "@ioredis/commands": "^1.1.1", + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.4", + "denque": "^2.1.0", + "lodash.defaults": "^4.2.0", + "lodash.isarguments": "^3.1.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ioredis" } }, - "node_modules/is-stream": { + "node_modules/ip": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", + "dev": true + }, + "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==", "dev": true, "engines": { - "node": ">=8" + "node": ">= 0.10" } }, - "node_modules/is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", "dev": true, "dependencies": { - "has-symbols": "^1.0.1" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -7604,713 +8966,784 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "node_modules/is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "node_modules/is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", "dev": true, "dependencies": { - "unc-path-regex": "^0.1.2" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-utf8": { + "node_modules/is-arrayish": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, - "node_modules/is-valid-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", - "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-valid-path": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-valid-path/-/is-valid-path-0.1.1.tgz", - "integrity": "sha1-EQ+f90w39mPh7HkV60UfLbk6yd8=", + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, "dependencies": { - "is-invalid-path": "^0.1.0" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, - "optional": true, "dependencies": { - "is-docker": "^2.0.0" + "hasown": "^2.0.0" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "node_modules/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==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "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==", + "node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", "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": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, - "bin": { - "semver": "bin/semver.js" + "engines": { + "node": ">=6" } }, - "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==", + "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==", "dev": true, "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" + "is-extglob": "^2.1.1" }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/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==", + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "dev": true + }, + "node_modules/is-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", + "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "engines": { + "node": ">= 0.4" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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": ">=8" + "node": ">=0.12.0" } }, - "node_modules/istanbul-lib-source-maps/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, "dependencies": { - "ms": "2.1.2" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=6.0" + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/istanbul-lib-source-maps/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/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==", + "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": ">=0.10.0" + "node": ">=8" } }, - "node_modules/istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, "engines": { "node": ">=8" } }, - "node_modules/istextorbinary": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-2.2.1.tgz", - "integrity": "sha512-TS+hoFl8Z5FAFMK38nhBkdLt44CclNRgDHWeMgsV8ko3nDlr/9UI2Sf839sW7enijf8oKsZYXRvM8g0it9Zmcw==", + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, "dependencies": { - "binaryextensions": "2", - "editions": "^1.3.3", - "textextensions": "2" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=0.12" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "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/is-set": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", + "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz", - "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==", + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", "dev": true, "dependencies": { - "@jest/core": "^26.6.3", - "import-local": "^3.0.2", - "jest-cli": "^26.6.3" - }, - "bin": { - "jest": "bin/jest.js" + "call-bind": "^1.0.2" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, "engines": { - "node": ">= 10.14.2" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-changed-files": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", - "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "execa": "^4.0.0", - "throat": "^5.0.0" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-cli": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", - "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, "dependencies": { - "@jest/core": "^26.6.3", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "is-ci": "^2.0.0", - "jest-config": "^26.6.3", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "prompts": "^2.0.1", - "yargs": "^15.4.1" - }, - "bin": { - "jest": "bin/jest.js" + "has-symbols": "^1.0.2" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-cli/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "node_modules/is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "which-typed-array": "^1.1.11" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-cli/node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "node_modules/is-weakmap": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", + "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-cli/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==", + "node_modules/is-weakset": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", + "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-cli/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==", + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true }, - "node_modules/jest-cli/node_modules/which-module": { + "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "node_modules/jest-cli/node_modules/y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", "dev": true }, - "node_modules/jest-cli/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==", + "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, - "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/jest-cli/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==", + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "node_modules/istanbul-lib-instrument/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, - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/jest-config/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" } }, - "node_modules/jest-diff/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "node_modules/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": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-docblock": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", - "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", "dev": true, "dependencies": { - "detect-newline": "^3.0.0" + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=8" } }, - "node_modules/jest-each": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", - "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", + "node_modules/jackspeak": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.5.tgz", + "integrity": "sha512-Ratx+B8WeXLAtRJn26hrhY8S1+Jz6pxPMrkrdkgb/NstTNiqMhX0/oFVu5wX+g5n6JlEu2LPsDJmY8nRP4+alw==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2" + "@isaacs/cliui": "^8.0.2" }, "engines": { - "node": ">= 10.14.2" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/jest-each/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "node_modules/jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" }, "engines": { - "node": ">=10" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/jest-environment-jsdom": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", - "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", + "node_modules/jest-changed-files": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", "dev": true, "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2", - "jsdom": "^16.4.0" + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-environment-node": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", - "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", + "node_modules/jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", "dev": true, "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "node_modules/jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", "dev": true, + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/jest-haste-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", - "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "node_modules/jest-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@types/graceful-fs": "^4.1.2", + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^26.0.0", - "jest-serializer": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "micromatch": "^4.0.2", - "sane": "^4.0.3", - "walker": "^1.0.7" + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "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": ">= 10.14.2" + "node": "*" }, - "optionalDependencies": { - "fsevents": "^2.1.2" + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/jest-jasmine2": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", - "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", "dev": true, "dependencies": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^26.6.2", - "is-generator-fn": "^2.0.0", - "jest-each": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2", - "throat": "^5.0.0" + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-jasmine2/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "detect-newline": "^3.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-leak-detector": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", - "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", + "node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", "dev": true, "dependencies": { - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-matcher-utils/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" }, "engines": { - "node": ">=10" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "optionalDependencies": { + "fsevents": "^2.3.2" } }, - "node_modules/jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-message-util/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { - "node": ">=10" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*" + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, "engines": { "node": ">=6" @@ -8325,421 +9758,272 @@ } }, "node_modules/jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", "dev": true, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", "slash": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-resolve-dependencies": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", - "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-resolve/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-runner": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", - "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", "dev": true, "dependencies": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", - "emittery": "^0.7.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.6.2", - "jest-leak-detector": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "source-map-support": "^0.5.6", - "throat": "^5.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-runner/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-runtime": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", - "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", - "dev": true, - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/globals": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/yargs": "^15.0.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", "chalk": "^4.0.0", - "cjs-module-lexer": "^0.6.0", + "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^15.4.1" - }, - "bin": { - "jest-runtime": "bin/jest-runtime.js" + "strip-bom": "^4.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-runtime/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "node_modules/jest-runtime/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "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": ">=10" + "node": "*" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-runtime/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/jest-runtime/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==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/jest-runtime/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/jest-runtime/node_modules/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 - }, - "node_modules/jest-runtime/node_modules/y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", - "dev": true - }, - "node_modules/jest-runtime/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" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/jest-runtime/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==", + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", "dev": true, "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" }, "engines": { - "node": ">=6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-serializer": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", - "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dev": true, "dependencies": { + "@jest/types": "^29.6.3", "@types/node": "*", - "graceful-fs": "^4.2.4" + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-snapshot": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", - "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", "dev": true, "dependencies": { - "@babel/types": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.0.0", + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", "chalk": "^4.0.0", - "expect": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", - "semver": "^7.3.2" + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-snapshot/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "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" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", + "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-util/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-validate": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", - "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "camelcase": "^6.0.0", - "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "leven": "^3.1.0", - "pretty-format": "^26.6.2" + "has-flag": "^4.0.0" }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/jest-validate/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "node_modules/jiti": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", + "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", "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" + "bin": { + "jiti": "bin/jiti.js" } }, - "node_modules/jest-watcher": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", - "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", - "dev": true, - "dependencies": { - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^26.6.2", - "string-length": "^4.0.1" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-watcher/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "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/jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "dev": true, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } + "node_modules/jju": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", + "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", + "dev": true }, "node_modules/joi": { "version": "17.3.0", @@ -8755,17 +10039,29 @@ } }, "node_modules/joiful": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/joiful/-/joiful-3.0.0.tgz", - "integrity": "sha512-NBFIWwN77+fgwwm88dyhcoMceBlaar5y5SVaHJzD7fmM4kvKUsjNh/nU0Bdv9zBYDe57nIPVBdSQXYgOKGHnCQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/joiful/-/joiful-3.0.2.tgz", + "integrity": "sha512-uXA4yH7LkoMUInqCuhX31wkV0IWePgb5+/khZS561sYWmjW3wXD37LvaDplg3/rBtgJv8BUXyjHElvGTwFB/+g==", "dev": true, "dependencies": { "joi": "17.3.0" }, "engines": { - "node": ">=8.10", + "node": ">=v10.22.0", "npm": ">=3.10.10", "yarn": ">=1.13.0" + }, + "peerDependencies": { + "reflect-metadata": "0.1.13" + } + }, + "node_modules/js-levenshtein": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, "node_modules/js-tokens": { @@ -8775,13 +10071,12 @@ "dev": true }, "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" @@ -8790,74 +10085,8 @@ "node_modules/jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, - "node_modules/jsdom": { - "version": "16.4.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.4.0.tgz", - "integrity": "sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w==", - "dev": true, - "dependencies": { - "abab": "^2.0.3", - "acorn": "^7.1.1", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.2.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.0", - "domexception": "^2.0.1", - "escodegen": "^1.14.1", - "html-encoding-sniffer": "^2.0.1", - "is-potential-custom-element-name": "^1.0.0", - "nwsapi": "^2.2.0", - "parse5": "5.1.1", - "request": "^2.88.2", - "request-promise-native": "^1.0.8", - "saxes": "^5.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^3.0.1", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0", - "ws": "^7.2.3", - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsdom/node_modules/ws": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.3.tgz", - "integrity": "sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA==", - "dev": true, - "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 - } - } + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true }, "node_modules/jsesc": { "version": "2.5.2", @@ -8871,6 +10100,18 @@ "node": ">=4" } }, + "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", @@ -8878,9 +10119,9 @@ "dev": true }, "node_modules/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==", "dev": true }, "node_modules/json-schema-traverse": { @@ -8892,23 +10133,20 @@ "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", "dev": true }, "node_modules/json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, "bin": { "json5": "lib/cli.js" }, @@ -8916,6 +10154,12 @@ "node": ">=6" } }, + "node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -8929,41 +10173,56 @@ } }, "node_modules/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==", "dev": true, - "engines": [ - "node >=0.6.0" - ], "dependencies": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", - "json-schema": "0.2.3", + "json-schema": "0.4.0", "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" } }, - "node_modules/just-debounce": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.0.0.tgz", - "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=", - "dev": true - }, "node_modules/kareem": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.1.tgz", - "integrity": "sha512-l3hLhffs9zqoDe8zjmb/mAN4B8VT3L56EUvKNqLFVs9YlFA+zx7ke1DO8STAdDyYNkeSo1nKmjuvQeI12So8Xw==", - "dev": true + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz", + "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } }, "node_modules/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==", + "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/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/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -8974,39 +10233,34 @@ } }, "node_modules/knex": { - "version": "0.21.17", - "resolved": "https://registry.npmjs.org/knex/-/knex-0.21.17.tgz", - "integrity": "sha512-kAt58lRwjzqwedApKF7luYPa7HsLb0oDiczwKrkZcekIzTmSow5YGK149S2C8HjH63R3NcOBo9+1rjvWnC1Paw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/knex/-/knex-3.1.0.tgz", + "integrity": "sha512-GLoII6hR0c4ti243gMs5/1Rb3B+AjwMOfjYm97pu0FOQa7JH56hgBxYf5WK2525ceSbBY1cjeZ9yk99GPMB6Kw==", "dev": true, "dependencies": { - "colorette": "1.2.1", - "commander": "^6.2.0", - "debug": "4.3.1", + "colorette": "2.0.19", + "commander": "^10.0.0", + "debug": "4.3.4", + "escalade": "^3.1.1", "esm": "^3.2.25", - "getopts": "2.2.5", + "get-package-type": "^0.1.0", + "getopts": "2.3.0", "interpret": "^2.2.0", - "liftoff": "3.1.0", - "lodash": "^4.17.20", - "pg-connection-string": "2.4.0", - "tarn": "^3.0.1", - "tildify": "2.0.0", - "v8flags": "^3.2.0" + "lodash": "^4.17.21", + "pg-connection-string": "2.6.2", + "rechoir": "^0.8.0", + "resolve-from": "^5.0.0", + "tarn": "^3.0.2", + "tildify": "2.0.0" }, "bin": { "knex": "bin/cli.js" }, "engines": { - "node": ">=10" - }, - "peerDependencies": { - "mssql": "^6.2.1", - "mysql": "^2.18.1", - "mysql2": "^2.1.0", - "pg": "^8.3.0", - "sqlite3": "^5.0.0" + "node": ">=16" }, "peerDependenciesMeta": { - "mssql": { + "better-sqlite3": { "optional": true }, "mysql": { @@ -9018,96 +10272,24 @@ "pg": { "optional": true }, + "pg-native": { + "optional": true + }, "sqlite3": { "optional": true - } - } - }, - "node_modules/knex/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { + }, + "tedious": { "optional": true } } }, - "node_modules/knex/node_modules/interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/knex/node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/knex/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/last-run": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", - "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=", - "dev": true, - "dependencies": { - "default-resolution": "^2.0.0", - "es6-weak-map": "^2.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "dependencies": { - "readable-stream": "^2.0.5" - }, - "engines": { - "node": ">= 0.6.3" - } - }, - "node_modules/lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "dependencies": { - "invert-kv": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/lead": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", - "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", + "node_modules/knex/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", "dev": true, - "dependencies": { - "flush-write-stream": "^1.0.2" - }, "engines": { - "node": ">= 0.10" + "node": ">=14" } }, "node_modules/leven": { @@ -9120,668 +10302,926 @@ } }, "node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/libphonenumber-js": { - "version": "1.9.7", - "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.9.7.tgz", - "integrity": "sha512-mDY7fCe6dXd1ZUvYr3Q0ZaoqZ1DVXDSjcqa3AMGyudEd0Tyf8PoHkQ+9NucIBy9C/wFITPwL3Ef9SA148q20Cw==", + "version": "1.10.37", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.37.tgz", + "integrity": "sha512-Z10PCaOCiAxbUxLyR31DNeeNugSVP6iv/m7UrSKS5JHziEMApJtgku4e9Q69pzzSC9LnQiM09sqsGf2ticZnMw==", "dev": true }, - "node_modules/liftoff": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", - "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", + "node_modules/lilconfig": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", + "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", "dev": true, - "dependencies": { - "extend": "^3.0.0", - "findup-sync": "^3.0.0", - "fined": "^1.0.1", - "flagged-respawn": "^1.0.0", - "is-plain-object": "^2.0.4", - "object.map": "^1.0.0", - "rechoir": "^0.6.2", - "resolve": "^1.1.7" - }, "engines": { - "node": ">= 0.8" + "node": ">=14" } }, "node_modules/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 }, - "node_modules/lint-staged": { - "version": "10.5.4", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.4.tgz", - "integrity": "sha512-EechC3DdFic/TdOPgj/RB3FicqE6932LTHCUm0Y2fsD9KGlLB+RwJl2q1IYBIvEsKzDOgn0D4gll+YxG5RsrKg==", + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", "dev": true, "dependencies": { - "chalk": "^4.1.0", - "cli-truncate": "^2.1.0", - "commander": "^6.2.0", - "cosmiconfig": "^7.0.0", - "debug": "^4.2.0", - "dedent": "^0.7.0", - "enquirer": "^2.3.6", - "execa": "^4.1.0", - "listr2": "^3.2.2", - "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" + "uc.micro": "^2.0.0" + } + }, + "node_modules/lint-staged": { + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.0.tgz", + "integrity": "sha512-TFZzUEV00f+2YLaVPWBWGAMq7So6yQx+GG8YRMDeOEIf95Zn5RyiLMsEiX4KTNl9vq/w+NqRJkLA1kPIo15ufQ==", + "dev": true, + "dependencies": { + "chalk": "5.3.0", + "commander": "11.1.0", + "debug": "4.3.4", + "execa": "8.0.1", + "lilconfig": "3.0.0", + "listr2": "8.0.0", + "micromatch": "4.0.5", + "pidtree": "0.6.0", + "string-argv": "0.3.2", + "yaml": "2.3.4" }, "bin": { "lint-staged": "bin/lint-staged.js" }, + "engines": { + "node": ">=18.12.0" + }, "funding": { "url": "https://opencollective.com/lint-staged" } }, "node_modules/lint-staged/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "engines": { - "node": ">=10" + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/lint-staged/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "node_modules/lint-staged/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, "dependencies": { - "ms": "2.1.2" + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" }, "engines": { - "node": ">=6.0" + "node": ">=16.17" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/lint-staged/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/listr2": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.2.3.tgz", - "integrity": "sha512-vUb80S2dSUi8YxXahO8/I/s29GqnOL8ozgHVLjfWQXa03BNEeS1TpBLjh2ruaqq5ufx46BRGvfymdBSuoXET5w==", + "node_modules/lint-staged/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "cli-truncate": "^2.1.0", - "figures": "^3.2.0", - "indent-string": "^4.0.0", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rxjs": "^6.6.3", - "through": "^2.3.8" - }, "engines": { - "node": ">=10.0.0" + "node": ">=16" }, - "peerDependencies": { - "enquirer": ">= 2.3.0 < 3" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/listr2/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "node_modules/lint-staged/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "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": ">=16.17.0" } }, - "node_modules/load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "node_modules/lint-staged/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/load-json-file/node_modules/parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "node_modules/lint-staged/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, - "dependencies": { - "error-ex": "^1.2.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/load-json-file/node_modules/strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "node_modules/lint-staged/node_modules/npm-run-path": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", + "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", "dev": true, "dependencies": { - "is-utf8": "^0.2.0" + "path-key": "^4.0.0" }, "engines": { - "node": ">=0.10.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/lint-staged/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, "dependencies": { - "p-locate": "^4.1.0" + "mimic-fn": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "node_modules/lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "dev": true - }, - "node_modules/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 - }, - "node_modules/lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "node_modules/lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" - }, - "node_modules/lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", - "dev": true - }, - "node_modules/lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "node_modules/lint-staged/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, - "dependencies": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "node_modules/lint-staged/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, - "dependencies": { - "lodash._reinterpolate": "^3.0.0" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash.xorby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.xorby/-/lodash.xorby-4.7.0.tgz", - "integrity": "sha1-nBmm+fBjputT3QPBtocXmYAUY9c=", - "dev": true - }, - "node_modules/log-symbols": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", - "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "node_modules/listr2": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.0.0.tgz", + "integrity": "sha512-u8cusxAcyqAiQ2RhYvV7kRKNLgUvtObIbhOX2NCXqvp1UU32xIg5CT22ykS2TPKJXZWJwtK3IKLiqAGlGNE+Zg==", "dev": true, "dependencies": { - "chalk": "^4.0.0" + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.0.0", + "rfdc": "^1.3.0", + "wrap-ansi": "^9.0.0" }, "engines": { - "node": ">=10" + "node": ">=18.0.0" } }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "node_modules/listr2/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "engines": { + "node": ">=12" }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "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==", + "node_modules/listr2/node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.0.0.tgz", + "integrity": "sha512-GPQHj7row82Hjo9hKZieKcHIhaAIKOJvFSIZXuCU9OASVZrMNUaZuz++SPVrBjnLsnk4k+z9f2EIypgxf2vNFw==", "dev": true, "dependencies": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-update/node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "node_modules/listr2/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/loglevel": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz", - "integrity": "sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==", + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, "engines": { - "node": ">= 0.6.0" + "node": ">=18" }, "funding": { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/loglevel" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/long": { + "node_modules/load-json-file": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - }, - "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==", + "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": { - "yallist": "^3.0.2" + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "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==", + "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": { - "semver": "^6.0.0" + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" + "node": ">=4" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/make-fetch-happen": { - "version": "8.0.12", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-8.0.12.tgz", - "integrity": "sha512-cBD7yM72ltWEV+xlLlbimnh5qHwr+thAb/cZLiaZhicVVPVN63BikBvL5OR68+8+z2fvBOgck628vGJ2ulgF6g==", + "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, - "dependencies": { - "agentkeepalive": "^4.1.3", - "cacache": "^15.0.5", - "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", - "promise-retry": "^1.1.1", - "socks-proxy-agent": "^5.0.0", - "ssri": "^8.0.0" - }, "engines": { - "node": ">= 10" + "node": ">=4" } }, - "node_modules/make-fetch-happen/node_modules/lru-cache": { + "node_modules/locate-path": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "dependencies": { - "yallist": "^4.0.0" + "p-locate": "^5.0.0" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-fetch-happen/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/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "node_modules/make-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", - "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "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.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" + }, + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==", + "dev": true + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "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==", + "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.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "dev": true + }, + "node_modules/log-update": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", + "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", "dev": true, "dependencies": { - "kind-of": "^6.0.2" + "ansi-escapes": "^6.2.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^7.0.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-iterator/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==", + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", + "integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==", "dev": true, + "dependencies": { + "type-fest": "^3.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, - "dependencies": { - "tmpl": "1.0.x" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", "dev": true, "dependencies": { - "object-visit": "^1.0.0" + "get-east-asian-width": "^1.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/matchdep": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", - "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=", + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", "dev": true, "dependencies": { - "findup-sync": "^2.0.0", - "micromatch": "^3.0.4", - "resolve": "^1.4.0", - "stack-trace": "0.0.10" + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" }, "engines": { - "node": ">= 0.10.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/matchdep/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "node_modules/log-update/node_modules/string-width": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.0.0.tgz", + "integrity": "sha512-GPQHj7row82Hjo9hKZieKcHIhaAIKOJvFSIZXuCU9OASVZrMNUaZuz++SPVrBjnLsnk4k+z9f2EIypgxf2vNFw==", "dev": true, "dependencies": { - "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" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/matchdep/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "node_modules/log-update/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "dependencies": { - "is-extendable": "^0.1.0" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/matchdep/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "node_modules/log-update/node_modules/type-fest": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/matchdep/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", "dev": true, "dependencies": { - "is-extendable": "^0.1.0" + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/loglevel": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.1.tgz", + "integrity": "sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg==", + "dev": true, + "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==", + "dev": true + }, + "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==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/magicli": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/magicli/-/magicli-0.0.8.tgz", + "integrity": "sha512-x/eBenweAHF+DsYy172sK4doRxZl0yrJnfxhLJiN7H6hPM3Ya0PfI6uBZshZ3ScFFSQD7HXgBqMdbnXKEZsO1g==", + "dev": true, + "dependencies": { + "cliss": "0.0.2", + "find-up": "^2.1.0", + "for-each-property": "0.0.4", + "inspect-property": "0.0.6" + } + }, + "node_modules/magicli/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/matchdep/node_modules/findup-sync": { + "node_modules/magicli/node_modules/locate-path": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", "dev": true, "dependencies": { - "detect-file": "^1.0.0", - "is-glob": "^3.1.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" }, "engines": { - "node": ">= 0.10" + "node": ">=4" } }, - "node_modules/matchdep/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "node_modules/magicli/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": ">=0.10.0" + "node": ">=4" } }, - "node_modules/matchdep/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "node_modules/magicli/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": { - "is-extglob": "^2.1.0" + "p-limit": "^1.1.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=4" + } + }, + "node_modules/magicli/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/matchdep/node_modules/is-number": { + "node_modules/magicli/node_modules/path-exists": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "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/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, "dependencies": { - "kind-of": "^3.0.2" + "semver": "^7.5.3" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/matchdep/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/make-fetch-happen": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", "dev": true, "dependencies": { - "is-buffer": "^1.1.5" + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" }, "engines": { - "node": ">=0.10.0" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/matchdep/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==", + "node_modules/make-fetch-happen/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": ">=0.10.0" + "node": ">=8" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" } }, - "node_modules/matchdep/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "node_modules/markdown-it": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.0.0.tgz", + "integrity": "sha512-seFjF0FIcPt4P9U39Bq1JYblX0KZCjDLFFQPHpL5AzHpqPEKtosxmdq/LTVZnjfH7tjt9BxStm+wXcDBNuYmzw==", "dev": true, "dependencies": { - "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" + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.0.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdownlint": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.33.0.tgz", + "integrity": "sha512-4lbtT14A3m0LPX1WS/3d1m7Blg+ZwiLq36WvjQqFGsX3Gik99NV+VXp/PW3n+Q62xyPdbvGOCfjPqjW+/SKMig==", + "dev": true, + "dependencies": { + "markdown-it": "14.0.0", + "markdownlint-micromark": "0.1.8" }, "engines": { - "node": ">=0.10.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" } }, - "node_modules/matchdep/node_modules/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=", + "node_modules/markdownlint-cli": { + "version": "0.38.0", + "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.38.0.tgz", + "integrity": "sha512-qkZRKJ4LVq6CJIkRIuJsEHvhWhm+FP0E7yhHvOMrrgdykgFWNYD4wuhZTjvigbJLTKPooP79yPiUDDZBCBI5JA==", "dev": true, "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "commander": "~11.1.0", + "get-stdin": "~9.0.0", + "glob": "~10.3.10", + "ignore": "~5.3.0", + "js-yaml": "^4.1.0", + "jsonc-parser": "~3.2.0", + "markdownlint": "~0.32.1", + "minimatch": "~9.0.3", + "run-con": "~1.3.2" + }, + "bin": { + "markdownlint": "markdownlint.js" }, "engines": { - "node": ">=0.10.0" + "node": ">=18" + } + }, + "node_modules/markdownlint-cli/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/markdownlint-cli/node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/markdownlint-cli/node_modules/linkify-it": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", + "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "dev": true, + "dependencies": { + "uc.micro": "^1.0.1" + } + }, + "node_modules/markdownlint-cli/node_modules/markdown-it": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.2.tgz", + "integrity": "sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "~3.0.1", + "linkify-it": "^4.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdownlint-cli/node_modules/markdownlint": { + "version": "0.32.1", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.32.1.tgz", + "integrity": "sha512-3sx9xpi4xlHlokGyHO9k0g3gJbNY4DI6oNEeEYq5gQ4W7UkiJ90VDAnuDl2U+yyXOUa6BX+0gf69ZlTUGIBp6A==", + "dev": true, + "dependencies": { + "markdown-it": "13.0.2", + "markdownlint-micromark": "0.1.7" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, + "node_modules/markdownlint-cli/node_modules/markdownlint-micromark": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.7.tgz", + "integrity": "sha512-BbRPTC72fl5vlSKv37v/xIENSRDYL/7X/XoFzZ740FGEbs9vZerLrIkFRY0rv7slQKxDczToYuMmqQFN61fi4Q==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/markdownlint-cli/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/markdownlint-cli/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/markdownlint-cli/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/markdownlint-micromark": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.8.tgz", + "integrity": "sha512-1ouYkMRo9/6gou9gObuMDnvZM8jC/ly3QCFQyoSPCS2XV1ZClU0xpKbL1Ar3bWWRT1RnBZkWUEiNKrI2CwiBQA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, + "node_modules/matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true, "engines": { "node": ">= 0.6" @@ -9791,13 +11231,21 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "dev": true + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", "dev": true, - "optional": true + "engines": { + "node": ">= 0.10.0" + } }, "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", "dev": true }, "node_modules/merge-stream": { @@ -9818,23 +11266,32 @@ "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { - "node": ">=8" + "node": ">=8.6" + } + }, + "node_modules/mikro-orm": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/mikro-orm/-/mikro-orm-6.0.2.tgz", + "integrity": "sha512-tq6d8zIzFpuRLe9rNqCRSw4LT9n844B4itM+SQNY7UB2t6UF3DlmpULQOsr8Msi28/hDXNeeDXtyZK86xlmk+A==", + "dev": true, + "engines": { + "node": ">= 18.12.0" } }, "node_modules/mime": { @@ -9850,21 +11307,21 @@ } }, "node_modules/mime-db": { - "version": "1.45.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", - "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==", + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.28", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz", - "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, "dependencies": { - "mime-db": "1.45.0" + "mime-db": "1.52.0" }, "engines": { "node": ">= 0.6" @@ -9880,9 +11337,10 @@ } }, "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -9891,21 +11349,21 @@ } }, "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/minipass": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", - "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", + "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" } }, "node_modules/minipass-collect": { @@ -9920,21 +11378,42 @@ "node": ">= 8" } }, + "node_modules/minipass-collect/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/minipass-fetch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.3.2.tgz", - "integrity": "sha512-/i4fX1ss+Dtwyk++OsAI6SEV+eE1dvI6W+0hORdjfruQ7VD5uYTetJIHcEMjWiEiszWjn2aAtP1CB/Q4KfeoYA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.3.tgz", + "integrity": "sha512-n5ITsTkDqYkYJZjcRWzZt9qnZKCT7nKCosJhHoj7S7zD+BP4jVbWs+odsniw5TA3E0sLomhTKOKjF86wf11PuQ==", "dev": true, "dependencies": { - "minipass": "^3.1.0", + "minipass": "^5.0.0", "minipass-sized": "^1.0.3", - "minizlib": "^2.0.0" + "minizlib": "^2.1.2" }, "engines": { - "node": ">=8" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" }, "optionalDependencies": { - "encoding": "^0.1.12" + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-fetch/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/minipass-flush": { @@ -9949,6 +11428,18 @@ "node": ">= 8" } }, + "node_modules/minipass-flush/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/minipass-pipeline": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", @@ -9961,6 +11452,18 @@ "node": ">=8" } }, + "node_modules/minipass-pipeline/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/minipass-sized": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", @@ -9973,11 +11476,17 @@ "node": ">=8" } }, - "node_modules/minipass/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "node_modules/minipass-sized/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/minizlib": { "version": "2.1.2", @@ -9992,23 +11501,16 @@ "node": ">= 8" } }, - "node_modules/minizlib/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "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": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" + "yallist": "^4.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/mkdirp": { @@ -10023,29 +11525,48 @@ "node": ">=10" } }, + "node_modules/mlly": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.4.2.tgz", + "integrity": "sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg==", + "dev": true, + "dependencies": { + "acorn": "^8.10.0", + "pathe": "^1.1.1", + "pkg-types": "^1.0.3", + "ufo": "^1.3.0" + } + }, "node_modules/mongodb": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.3.tgz", - "integrity": "sha512-rOZuR0QkodZiM+UbQE5kDsJykBqWi0CL4Ec2i1nrGrUI3KO11r6Fbxskqmq3JK2NH7aW4dcccBuUujAP0ERl5w==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.9.0.tgz", + "integrity": "sha512-g+GCMHN1CoRUA+wb1Agv0TI4YTSiWr42B5ulkiAfLLHitGK1R+PkSAf3Lr5rPZwi/3F04LiaZEW0Kxro9Fi2TA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "bl": "^2.2.1", - "bson": "^1.1.4", - "denque": "^1.4.1", - "require_optional": "^1.0.1", - "safe-buffer": "^5.1.2" + "bson": "^5.5.0", + "mongodb-connection-string-url": "^2.6.0", + "socks": "^2.7.1" }, "engines": { - "node": ">=4" + "node": ">=14.20.1" }, "optionalDependencies": { - "saslprep": "^1.0.0" + "@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": { - "aws4": { + "@aws-sdk/credential-providers": { "optional": true }, - "bson-ext": { + "@mongodb-js/zstd": { "optional": true }, "kerberos": { @@ -10054,123 +11575,182 @@ "mongodb-client-encryption": { "optional": true }, - "mongodb-extjson": { - "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==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@types/whatwg-url": "^8.2.1", + "whatwg-url": "^11.0.0" + } + }, "node_modules/mongoose": { - "version": "5.10.18", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.10.18.tgz", - "integrity": "sha512-vaLUzBpUxqacoCqP/xXWMg/uVwCDrlc8LvYjDXCf8hdApvX/CXa0HLa7v2ieFaVd5Fgv3W2QXODLoC4Z/abbNw==", - "dev": true, - "dependencies": { - "bson": "^1.1.4", - "kareem": "2.3.1", - "mongodb": "3.6.3", - "mongoose-legacy-pluralize": "1.0.2", - "mpath": "0.7.0", - "mquery": "3.2.2", - "ms": "2.1.2", - "regexp-clone": "1.0.0", - "safe-buffer": "5.2.1", - "sift": "7.0.1", - "sliced": "1.0.1" + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.2.0.tgz", + "integrity": "sha512-la93n6zCYRbPS+c5N9oTDAktvREy5OT9OCljp1Tah0y3+p8UPMTAoabWaLZMdzYruOtF9/9GRf6MasaZjiZP1A==", + "dev": true, + "dependencies": { + "bson": "^6.2.0", + "kareem": "2.5.1", + "mongodb": "6.3.0", + "mpath": "0.9.0", + "mquery": "5.0.0", + "ms": "2.1.3", + "sift": "16.0.1" }, "engines": { - "node": ">=4.0.0" + "node": ">=16.20.1" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/mongoose" } }, - "node_modules/mongoose-legacy-pluralize": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz", - "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==", + "node_modules/mongoose/node_modules/@types/whatwg-url": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.4.tgz", + "integrity": "sha512-lXCmTWSHJvf0TRSO58nm978b8HJ/EdsSsEKLd3ODHFjo+3VGAyyTp4v50nWvwtzBxSMQrVOK7tcuN0zGPLICMw==", "dev": true, - "peerDependencies": { - "mongoose": "*" + "dependencies": { + "@types/webidl-conversions": "*" } }, - "node_modules/mongoose/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "node_modules/mongoose/node_modules/bson": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.3.0.tgz", + "integrity": "sha512-balJfqwwTBddxfnidJZagCBPP/f48zj9Sdp3OJswREOgsJzHiQSaOIAtApSgDQFYgHqAvFkp53AFSqjMDZoTFw==", + "dev": true, + "engines": { + "node": ">=16.20.1" + } }, - "node_modules/mongoose/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==", + "node_modules/mongoose/node_modules/mongodb": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.3.0.tgz", + "integrity": "sha512-tt0KuGjGtLUhLoU263+xvQmPHEGTw5LbcNC73EoFRYgSHwZt5tsoJC110hDyO1kjQzpgNrpdcSza9PknWN4LrA==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" + "dependencies": { + "@mongodb-js/saslprep": "^1.1.0", + "bson": "^6.2.0", + "mongodb-connection-string-url": "^3.0.0" + }, + "engines": { + "node": ">=16.20.1" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.188.0", + "@mongodb-js/zstd": "^1.1.0", + "gcp-metadata": "^5.2.0", + "kerberos": "^2.0.1", + "mongodb-client-encryption": ">=6.0.0 <7", + "snappy": "^7.2.2", + "socks": "^2.7.1" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" + "@mongodb-js/zstd": { + "optional": true }, - { - "type": "consulting", - "url": "https://feross.org/support" + "gcp-metadata": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + }, + "socks": { + "optional": true } - ] + } }, - "node_modules/mpath": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.7.0.tgz", - "integrity": "sha512-Aiq04hILxhz1L+f7sjGyn7IxYzWm1zLNNXcfhDtx04kZ2Gk7uvFdgZ8ts1cWa/6d0TQmag2yR8zSGZUmp0tFNg==", + "node_modules/mongoose/node_modules/mongodb-connection-string-url": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.0.tgz", + "integrity": "sha512-t1Vf+m1I5hC2M5RJx/7AtxgABy1cZmIPQRMXw+gEIPn/cZNF3Oiy+l0UIypUwVB5trcWHq3crg2g3uAR9aAwsQ==", + "dev": true, + "dependencies": { + "@types/whatwg-url": "^11.0.2", + "whatwg-url": "^13.0.0" + } + }, + "node_modules/mongoose/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/mongoose/node_modules/tr46": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", "dev": true, + "dependencies": { + "punycode": "^2.3.0" + }, "engines": { - "node": ">=4.0.0" + "node": ">=14" } }, - "node_modules/mquery": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.2.tgz", - "integrity": "sha512-XB52992COp0KP230I3qloVUbkLUxJIu328HBP2t2EsxSFtf4W1HPSOBWOXf1bqxK4Xbb66lfMJ+Bpfd9/yZE1Q==", + "node_modules/mongoose/node_modules/whatwg-url": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", + "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", "dev": true, "dependencies": { - "bluebird": "3.5.1", - "debug": "3.1.0", - "regexp-clone": "^1.0.0", - "safe-buffer": "5.1.2", - "sliced": "1.0.1" + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" }, + "engines": { + "node": ">=16" + } + }, + "node_modules/mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "dev": true, "engines": { "node": ">=4.0.0" } }, - "node_modules/mquery/node_modules/debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "node_modules/mquery": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", + "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", "dev": true, "dependencies": { - "ms": "2.0.0" + "debug": "4.x" + }, + "engines": { + "node": ">=14.0.0" } }, "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/mute-stdout": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", - "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", - "dev": true, - "engines": { - "node": ">= 0.10" - } + "node_modules/mvdan-sh": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/mvdan-sh/-/mvdan-sh-0.10.1.tgz", + "integrity": "sha512-kMbrH0EObaKmK3nVRKUIIya1dpASHIEusM13S4V1ViHFuxuNxCo+arxoa6j/dbV22YBGjl7UKJm9QQKJ2Crzhg==", + "dev": true }, "node_modules/mz": { "version": "2.7.0", @@ -10183,110 +11763,103 @@ "thenify-all": "^1.0.0" } }, - "node_modules/nan": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", - "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", - "dev": true, - "optional": true - }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "dependencies": { - "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" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/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/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, "node_modules/negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true, "engines": { "node": ">= 0.6" } }, - "node_modules/next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", - "dev": true - }, "node_modules/nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, + "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==", + "dev": true + }, "node_modules/node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "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/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "node_modules/node-fetch-native": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.1.tgz", + "integrity": "sha512-bW9T/uJDPAJB2YNYEpWzE54U5O3MQidXsOyTfnbKYtTtFexRvGzb1waphBN4ZwP6EcIvYYEOwW0b72BpAqydTw==", "dev": true }, - "node_modules/node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "node_modules/node-fetch/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/node-fetch/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/node-fetch/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, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" } }, - "node_modules/node-notifier": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.1.tgz", - "integrity": "sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA==", + "node_modules/node-html-parser": { + "version": "6.1.12", + "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-6.1.12.tgz", + "integrity": "sha512-/bT/Ncmv+fbMGX96XG9g05vFt43m/+SYKIs9oAemQVYyVcZmDAI2Xq/SbNcpOA35eF0Zk2av3Ksf+Xk8Vt8abA==", "dev": true, - "optional": true, "dependencies": { - "growly": "^1.3.0", - "is-wsl": "^2.2.0", - "semver": "^7.3.2", - "shellwords": "^0.1.1", - "uuid": "^8.3.0", - "which": "^2.0.2" + "css-select": "^5.1.0", + "he": "1.2.0" } }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", + "dev": true + }, "node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -10300,9 +11873,9 @@ } }, "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, "bin": { "semver": "bin/semver" @@ -10317,153 +11890,244 @@ "node": ">=0.10.0" } }, - "node_modules/now-and-later": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", - "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", + "node_modules/npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", "dev": true, "dependencies": { - "once": "^1.3.2" + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + }, + "bin": { + "npm-run-all": "bin/npm-run-all/index.js", + "run-p": "bin/run-p/index.js", + "run-s": "bin/run-s/index.js" }, "engines": { - "node": ">= 0.10" + "node": ">= 4" } }, - "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==", + "node_modules/npm-run-all/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "dependencies": { - "path-key": "^3.0.0" + "color-convert": "^1.9.0" }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/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=", + "node_modules/npm-run-all/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "node_modules/npm-run-all/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/npm-run-all/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "node_modules/npm-run-all/node_modules/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, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, "engines": { - "node": "*" + "node": ">=4.8" } }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "node_modules/npm-run-all/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=0.8.0" } }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "node_modules/npm-run-all/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==", "dev": true, - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/object-copy/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "node_modules/npm-run-all/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/object-copy/node_modules/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=", + "node_modules/npm-run-all/node_modules/pidtree": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", + "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", "dev": true, - "dependencies": { - "kind-of": "^3.0.2" + "bin": { + "pidtree": "bin/pidtree.js" }, "engines": { - "node": ">=0.10.0" + "node": ">=0.10" } }, - "node_modules/object-copy/node_modules/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=", + "node_modules/npm-run-all/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, - "dependencies": { - "kind-of": "^3.0.2" + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/npm-run-all/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/object-copy/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "node_modules/npm-run-all/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-all/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==", "dev": true, "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "has-flag": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/object-copy/node_modules/is-descriptor/node_modules/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==", + "node_modules/npm-run-all/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "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": ">=0.10.0" + "node": ">=8" } }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "dev": true, "dependencies": { - "is-buffer": "^1.1.5" + "boolbase": "^1.0.0" }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/object-inspect": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", - "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -10477,36 +12141,89 @@ "node": ">= 0.4" } }, - "node_modules/object-path": { - "version": "0.11.5", - "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.5.tgz", - "integrity": "sha512-jgSbThcoR/s+XumvGMTMf81QVBmah+/Q7K7YduKeKVWL7N111unR2d6pZZarSk6kY/caeNxUDyxOvMWyzoU2eg==", + "node_modules/object-to-arguments": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/object-to-arguments/-/object-to-arguments-0.0.8.tgz", + "integrity": "sha512-BfWfuAwuhdH1bhMG5EG90WE/eckkBhBvnke8eSEkCDXoLE9Jk5JwYGTbCx1ehGwV48HvBkn62VukPBdlMUOY9w==", + "dev": true, + "dependencies": { + "inspect-parameters-declaration": "0.0.10", + "magicli": "0.0.5", + "split-skip": "0.0.2", + "stringify-parameters": "0.0.4", + "unpack-string": "0.0.2" + }, + "bin": { + "object-to-arguments": "bin/cli.js" + } + }, + "node_modules/object-to-arguments/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/object-to-arguments/node_modules/get-stdin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", + "integrity": "sha512-jZV7n6jGE3Gt7fgSTJoz91Ak5MuTLwMwkoYdjxuJ/AmjIsE1UC03y/IWkZCQGEvVNS9qoRNwy5BCqxImv0FVeA==", "dev": true, "engines": { - "node": ">= 10.12.0" + "node": ">=0.12.0" } }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "node_modules/object-to-arguments/node_modules/inspect-function": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/inspect-function/-/inspect-function-0.2.2.tgz", + "integrity": "sha512-becs5gzcHwPrlHawscYkyQ/ShiOiosrXPhA5RVZ3qyWH4aWdD52RnMfXq/dwQXciHwiieD8aIPwdIWYv6eL+sQ==", + "dev": true, + "dependencies": { + "split-skip": "0.0.1", + "unpack-string": "0.0.2" + } + }, + "node_modules/object-to-arguments/node_modules/inspect-function/node_modules/split-skip": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/split-skip/-/split-skip-0.0.1.tgz", + "integrity": "sha512-7dkvq+gofI4M8zx4iZnEZ3O1s7FP4Y/iaIDHJh5RyWrs8idcPauFi2OZe3TBi36fLvR2j5z3kSzVtz6IhPdncQ==", + "dev": true + }, + "node_modules/object-to-arguments/node_modules/inspect-parameters-declaration": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/inspect-parameters-declaration/-/inspect-parameters-declaration-0.0.10.tgz", + "integrity": "sha512-L8/Bvt9iDXQTZ63xY5/MAyvzz+FagR/qGh1kIXvUpsno3AAE0Z95d6QO51zrcMGaEGpwh/57idfMxTxbvRmytg==", "dev": true, "dependencies": { - "isobject": "^3.0.0" + "magicli": "0.0.5", + "split-skip": "0.0.2", + "stringify-parameters": "0.0.4", + "unpack-string": "0.0.2" }, - "engines": { - "node": ">=0.10.0" + "bin": { + "inspect-parameters-declaration": "bin/cli.js" + } + }, + "node_modules/object-to-arguments/node_modules/magicli": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/magicli/-/magicli-0.0.5.tgz", + "integrity": "sha512-wZbMtnl2v1b+Jp3xlqA9FU/O4I6YhGXR8xSY/eU2+gDAvut/F+W3gl4qs61iL4LELC7jqSAE6aAD5668EbmQHA==", + "dev": true, + "dependencies": { + "commander": "^2.9.0", + "get-stdin": "^5.0.1", + "inspect-function": "^0.2.1", + "pipe-functions": "^1.2.0" } }, "node_modules/object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", "object-keys": "^1.1.1" }, "engines": { @@ -10516,80 +12233,81 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "node_modules/object.entries": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", + "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", "dev": true, "dependencies": { - "array-each": "^1.0.1", - "array-slice": "^1.0.0", - "for-own": "^1.0.0", - "isobject": "^3.0.0" + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, - "node_modules/object.getownpropertydescriptors": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", - "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", + "node_modules/object.fromentries": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", + "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "engines": { - "node": ">= 0.8" + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.map": { + "node_modules/object.groupby": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", - "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", + "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", "dev": true, "dependencies": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1" } }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "node_modules/object.values": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", "dev": true, "dependencies": { - "isobject": "^3.0.1" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.reduce": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", - "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=", + "node_modules/ofetch": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/ofetch/-/ofetch-1.3.3.tgz", + "integrity": "sha512-s1ZCMmQWXy4b5K/TW9i/DtiN8Ku+xCiHcjQ6/J/nDdssirrQNOoB165Zu8EqLMA2lln1JUth9a0aW9Ap2ctrUg==", "dev": true, "dependencies": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" + "destr": "^2.0.1", + "node-fetch-native": "^1.4.0", + "ufo": "^1.3.0" } }, "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, "dependencies": { "ee-first": "1.1.1" @@ -10601,7 +12319,8 @@ "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, "dependencies": { "wrappy": "1" } @@ -10621,101 +12340,53 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/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, - "bin": { - "opencollective-postinstall": "index.js" - } - }, "node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "@aashutoshrathi/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" }, "engines": { "node": ">= 0.8.0" } }, - "node_modules/ordered-read-streams": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", - "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", - "dev": true, - "dependencies": { - "readable-stream": "^2.0.1" - } - }, - "node_modules/os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "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==", "dev": true, "dependencies": { - "lcid": "^1.0.0" + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "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" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "dependencies": { - "p-try": "^2.0.0" + "p-limit": "^3.0.2" }, "engines": { - "node": ">=6" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "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/p-map": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", @@ -10740,45 +12411,16 @@ "node": ">=6" } }, - "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==", - "dev": true - }, "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==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parent-require": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parent-require/-/parent-require-1.0.0.tgz", - "integrity": "sha1-dGoWdjgIOoYLDu9nMssn7UbDKXc=", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/parse-filepath": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", - "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-2.0.0.tgz", + "integrity": "sha512-uo0Z9JJeWzv8BG+tRcapBKNJ0dro9cLyczGzulS6EfeyAdeC9sbojtW6XwvYxJkEne9En+J2XEl4zyglVeIwFg==", "dev": true, "dependencies": { - "is-absolute": "^1.0.0", - "map-cache": "^0.2.0", - "path-root": "^0.1.1" + "callsites": "^3.1.0" }, "engines": { - "node": ">=0.8" + "node": ">=8" } }, "node_modules/parse-json": { @@ -10799,24 +12441,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/parse-node-version": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", - "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/parse5": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", @@ -10847,21 +12471,6 @@ "node": ">= 0.8" } }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -10874,7 +12483,8 @@ "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -10889,36 +12499,40 @@ } }, "node_modules/path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "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-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", "dev": true, "dependencies": { - "path-root-regex": "^0.1.0" + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", + "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": "14 || >=16.14" } }, "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", "dev": true }, "node_modules/path-type": { @@ -10930,31 +12544,44 @@ "node": ">=8" } }, + "node_modules/pathe": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.1.tgz", + "integrity": "sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==", + "dev": true + }, + "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": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", "dev": true }, "node_modules/pg": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.5.1.tgz", - "integrity": "sha512-9wm3yX9lCfjvA98ybCyw2pADUivyNWT/yIP4ZcDVpMN0og70BUWYEGXPCTAQdGTAqnytfRADb7NERrY1qxhIqw==", + "version": "8.11.5", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.5.tgz", + "integrity": "sha512-jqgNHSKL5cbDjFlHyYsCXmQDrfIX/3RsNwYqpd4N0Kt8niLuNoRNH+aazv6cOd43gPh9Y4DjQCtb+X0MH0Hvnw==", "dev": true, "dependencies": { - "buffer-writer": "2.0.0", - "packet-reader": "1.0.0", - "pg-connection-string": "^2.4.0", - "pg-pool": "^3.2.2", - "pg-protocol": "^1.4.0", + "pg-connection-string": "^2.6.4", + "pg-pool": "^3.6.2", + "pg-protocol": "^1.6.1", "pg-types": "^2.1.0", "pgpass": "1.x" }, "engines": { "node": ">= 8.0.0" }, + "optionalDependencies": { + "pg-cloudflare": "^1.1.1" + }, "peerDependencies": { - "pg-native": ">=2.0.0" + "pg-native": ">=3.0.1" }, "peerDependenciesMeta": { "pg-native": { @@ -10962,11 +12589,18 @@ } } }, - "node_modules/pg-connection-string": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.4.0.tgz", - "integrity": "sha512-3iBXuv7XKvxeMrIgym7njT+HlZkwZqqGX4Bu9cci8xHZNT+Um1gWKqCsAzcC0d95rcKMU5WBg6YRUcHyV0HZKQ==", - "dev": 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==", + "dev": true, + "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==", + "dev": true }, "node_modules/pg-int8": { "version": "1.0.1", @@ -10978,18 +12612,18 @@ } }, "node_modules/pg-pool": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.2.2.tgz", - "integrity": "sha512-ORJoFxAlmmros8igi608iVEbQNNZlp89diFVx6yV5v+ehmpMY9sK6QgpmgoXbmkNaBAx8cOOZh9g80kJv1ooyA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.2.tgz", + "integrity": "sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg==", "dev": true, "peerDependencies": { "pg": ">=8.0" } }, "node_modules/pg-protocol": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.4.0.tgz", - "integrity": "sha512-El+aXWcwG/8wuFICMQjM5ZSAm6OWiJicFdNYo+VY3QP+8vI4SvLIWVe51PppTzMhikUJR+PsyIFKqfdXPz/yxA==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.1.tgz", + "integrity": "sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==", "dev": true }, "node_modules/pg-types": { @@ -11008,19 +12642,31 @@ "node": ">=4" } }, + "node_modules/pg/node_modules/pg-connection-string": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.4.tgz", + "integrity": "sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA==", + "dev": true + }, "node_modules/pgpass": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.4.tgz", - "integrity": "sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", "dev": true, "dependencies": { - "split2": "^3.1.1" + "split2": "^4.1.0" } }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, "node_modules/picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "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" @@ -11029,19 +12675,31 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "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": ">=0.10.0" + "node": ">=4" } }, "node_modules/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, "engines": { "node": ">=0.10.0" @@ -11050,7 +12708,7 @@ "node_modules/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, "dependencies": { "pinkie": "^2.0.0" @@ -11059,14 +12717,17 @@ "node": ">=0.10.0" } }, + "node_modules/pipe-functions": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/pipe-functions/-/pipe-functions-1.3.0.tgz", + "integrity": "sha512-6Rtbp7criZRwedlvWbUYxqlqJoAlMvYHo2UcRWq79xZ54vZcaNHpVBOcWkX3ErT2aUA69tv+uiv4zKJbhD/Wgg==", + "dev": true + }, "node_modules/pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", "dev": true, - "dependencies": { - "node-modules-regexp": "^1.0.0" - }, "engines": { "node": ">= 6" } @@ -11083,49 +12744,67 @@ "node": ">=8" } }, - "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==", + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "dependencies": { - "semver-compare": "^1.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/plugin-error": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", - "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "dependencies": { - "ansi-colors": "^1.0.1", - "arr-diff": "^4.0.0", - "arr-union": "^3.1.0", - "extend-shallow": "^3.0.2" + "p-locate": "^4.1.0" }, "engines": { - "node": ">= 0.10" + "node": ">=8" } }, - "node_modules/plugin-error/node_modules/ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "dependencies": { - "ansi-wrap": "^0.1.0" + "p-try": "^2.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/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=", + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" + } + }, + "node_modules/pkg-types": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz", + "integrity": "sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==", + "dev": true, + "dependencies": { + "jsonc-parser": "^3.2.0", + "mlly": "^1.2.0", + "pathe": "^1.1.0" } }, "node_modules/postgres-array": { @@ -11140,7 +12819,7 @@ "node_modules/postgres-bytea": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", - "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", "dev": true, "engines": { "node": ">=0.10.0" @@ -11168,48 +12847,72 @@ } }, "node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "engines": { "node": ">= 0.8.0" } }, "node_modules/prettier": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", - "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", "dev": true, "bin": { - "prettier": "bin-prettier.js" + "prettier": "bin/prettier.cjs" }, "engines": { - "node": ">=10.13.0" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-plugin-sh": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/prettier-plugin-sh/-/prettier-plugin-sh-0.14.0.tgz", + "integrity": "sha512-hfXulj5+zEl/ulrO5kMuuTPKmXvOg0bnLHY1hKFNN/N+/903iZbNp8NyZBTsgI8dtkSgFfAEIQq0IQTyP1ZVFQ==", + "dev": true, + "dependencies": { + "mvdan-sh": "^0.10.1", + "sh-syntax": "^0.4.1" + }, + "engines": { + "node": ">=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + }, + "peerDependencies": { + "prettier": "^3.0.3" } }, "node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">= 10" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "engines": { - "node": ">= 0.8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/process-nextick-args": { @@ -11218,38 +12921,32 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, "node_modules/promise-retry": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-1.1.1.tgz", - "integrity": "sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", "dev": true, "dependencies": { - "err-code": "^1.0.0", - "retry": "^0.10.0" + "err-code": "^2.0.2", + "retry": "^0.12.0" }, "engines": { - "node": ">=0.12" + "node": ">=10" } }, "node_modules/promise-retry/node_modules/retry": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", - "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", "dev": true, "engines": { - "node": "*" + "node": ">= 4" } }, "node_modules/prompts": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz", - "integrity": "sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, "dependencies": { "kleur": "^3.0.3", @@ -11260,12 +12957,12 @@ } }, "node_modules/proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "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==", "dev": true, "dependencies": { - "forwarded": "~0.1.2", + "forwarded": "0.2.0", "ipaddr.js": "1.9.1" }, "engines": { @@ -11273,166 +12970,125 @@ } }, "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", "dev": true }, - "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/pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "dependencies": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - } - }, - "node_modules/pumpify/node_modules/pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "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==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true, "engines": { "node": ">=6" } }, - "node_modules/qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", "dev": true, "engines": { - "node": ">=0.6" + "node": ">=6" } }, - "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==", + "node_modules/pure-rand": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", + "integrity": "sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==", "dev": true, - "engines": { - "node": ">= 0.6" - } + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] }, - "node_modules/raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, "dependencies": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" + "side-channel": "^1.0.4" }, "engines": { - "node": ">= 0.8" + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/raw-body/node_modules/http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "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==", + "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/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==", "dev": true, - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, "engines": { "node": ">= 0.6" } }, - "node_modules/raw-body/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, "node_modules/react-is": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", - "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, "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==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", "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" + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "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==", + "node_modules/read-pkg/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "pify": "^3.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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/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": ">=4" } }, "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==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, "dependencies": { "core-util-is": "~1.0.0", @@ -11444,40 +13100,34 @@ "util-deprecate": "~1.0.1" } }, - "node_modules/readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } + "node_modules/readable-stream/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/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/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", "dev": true, "dependencies": { - "resolve": "^1.1.6" + "resolve": "^1.20.0" }, "engines": { - "node": ">= 0.10" + "node": ">= 10.13.0" } }, - "node_modules/redis-commands": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz", - "integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==", - "dev": true - }, "node_modules/redis-errors": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", - "integrity": "sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=", + "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", "dev": true, "engines": { "node": ">=4" @@ -11486,7 +13136,7 @@ "node_modules/redis-parser": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", - "integrity": "sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=", + "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", "dev": true, "dependencies": { "redis-errors": "^1.0.0" @@ -11495,126 +13145,47 @@ "node": ">=4" } }, + "node_modules/reduce-flatten": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz", + "integrity": "sha512-j5WfFJfc9CoXv/WbwVLHq74i/hdTUpy+iNC534LxczMRP67vJeK3V9JOdnL0N1cIRbn9mYhE2yVjvvKXDxvNXQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/reflect-metadata": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", "dev": true }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "node_modules/regexp.prototype.flags": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", + "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", "dev": true, "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "set-function-name": "^2.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regexp-clone": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz", - "integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==", - "dev": true - }, - "node_modules/remove-bom-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", - "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5", - "is-utf8": "^0.2.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/remove-bom-stream": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", - "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", - "dev": true, - "dependencies": { - "remove-bom-buffer": "^3.0.0", - "safe-buffer": "^5.1.0", - "through2": "^2.0.3" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/remove-bom-stream/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/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 - }, - "node_modules/repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", "dev": true, "engines": { "node": ">=0.10" } }, - "node_modules/replace-ext": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", - "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/replace-homedir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", - "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=", - "dev": true, - "dependencies": { - "homedir-polyfill": "^1.0.1", - "is-absolute": "^1.0.0", - "remove-trailing-separator": "^1.1.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/replacestream": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/replacestream/-/replacestream-4.0.3.tgz", - "integrity": "sha512-AC0FiLS352pBBiZhd4VXB1Ab/lh0lEgpP+GGvZqbQh8a5cmXVoTe5EX/YeTFArnp4SRGTHh1qCHu9lGs1qG8sA==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.3", - "object-assign": "^4.0.1", - "readable-stream": "^2.0.2" - } - }, "node_modules/request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -11647,58 +13218,6 @@ "node": ">= 6" } }, - "node_modules/request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dev": true, - "dependencies": { - "lodash": "^4.17.19" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request-promise-core/node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", - "dev": true, - "dependencies": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - }, - "engines": { - "node": ">=0.12.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request-promise-native/node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/request/node_modules/form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", @@ -11714,87 +13233,45 @@ } }, "node_modules/request/node_modules/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.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", "dev": true, "engines": { "node": ">=0.6" } }, - "node_modules/request/node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, "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.", "dev": true, "bin": { "uuid": "bin/uuid" } }, - "node_modules/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, - "dependencies": { - "resolve-from": "^2.0.0", - "semver": "^5.1.0" - } - }, - "node_modules/require_optional/node_modules/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require_optional/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/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, "node_modules/resolve": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", - "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "version": "1.22.6", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz", + "integrity": "sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==", "dev": true, "dependencies": { - "is-core-module": "^2.1.0", - "path-parse": "^1.0.6" + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -11812,7 +13289,7 @@ "node": ">=8" } }, - "node_modules/resolve-cwd/node_modules/resolve-from": { + "node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", @@ -11821,73 +13298,50 @@ "node": ">=8" } }, - "node_modules/resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", - "dev": true, - "dependencies": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - }, - "engines": { - "node": ">=0.10.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==", + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "dev": true, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, - "node_modules/resolve-options": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", - "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", + "node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", "dev": true, - "dependencies": { - "value-or-function": "^3.0.0" - }, "engines": { - "node": ">= 0.10" + "node": ">=10" } }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "deprecated": "https://github.com/lydell/resolve-url#deprecated", - "dev": true - }, "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==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", "dev": true, "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/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, - "engines": { - "node": ">=0.12" - } + "node_modules/restore-cursor/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/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", "dev": true, "engines": { "node": ">= 4" @@ -11903,6 +13357,12 @@ "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -11918,19 +13378,71 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/rsvp": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", - "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "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/roarr": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", + "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "dev": true, + "dependencies": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/run-con": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.3.2.tgz", + "integrity": "sha512-CcfE+mYiTcKEzg0IqS08+efdnH0oJ3zV0wSUFBNrMHMuxCtXvBCLzCJHatwuXDcu/RlhjTziTo/a1ruQik6/Yg==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~4.1.0", + "minimist": "^1.2.8", + "strip-json-comments": "~3.1.1" + }, + "bin": { + "run-con": "cli.js" + } + }, + "node_modules/run-con/node_modules/ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", "dev": true, "engines": { - "node": "6.* || >= 7.*" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/run-parallel": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz", - "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==", + "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, "funding": [ { @@ -11945,39 +13457,61 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } }, - "node_modules/rxjs": { - "version": "6.6.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz", - "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==", + "node_modules/safe-array-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", + "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", "dev": true, "dependencies": { - "tslib": "^1.9.0" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" }, "engines": { - "npm": ">=2.0.0" + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "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/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": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "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/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", "dev": true, "dependencies": { - "ret": "~0.1.10" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/safer-buffer": { @@ -11986,15037 +13520,2495 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "node_modules/sane": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", - "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "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": { - "@cnakazawa/watch": "^1.0.3", - "anymatch": "^2.0.0", - "capture-exit": "^2.0.0", - "exec-sh": "^0.3.2", - "execa": "^1.0.0", - "fb-watchman": "^2.0.0", - "micromatch": "^3.1.4", - "minimist": "^1.1.1", - "walker": "~1.0.5" + "commander": "^2.8.1" }, "bin": { - "sane": "src/cli.js" - }, - "engines": { - "node": "6.* || 8.* || >= 10.*" + "seek-bunzip": "bin/seek-bunzip", + "seek-table": "bin/seek-bzip-table" } }, - "node_modules/sane/node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } + "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/sane/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, + "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": { - "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" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/sane/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, + "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/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": { - "is-extendable": "^0.1.0" + "yallist": "^4.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/sane/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "dev": true, "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "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": ">=4.8" + "node": ">= 0.8.0" } }, - "node_modules/sane/node_modules/execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "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==", "dev": true, "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=6" + "ms": "2.0.0" } }, - "node_modules/sane/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "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==", + "dev": true + }, + "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==", + "dev": true + }, + "node_modules/serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", "dev": true, "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" + "type-fest": "^0.13.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/sane/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "node_modules/serialize-error/node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/sane/node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "node_modules/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==", "dev": true, "dependencies": { - "pump": "^3.0.0" + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" }, "engines": { - "node": ">=6" - } - }, - "node_modules/sane/node_modules/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, - "engines": { - "node": ">=0.10.0" + "node": ">= 0.8.0" } }, - "node_modules/sane/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", "dev": true, "dependencies": { - "kind-of": "^3.0.2" + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, - "node_modules/sane/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/set-function-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", + "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", "dev": true, "dependencies": { - "is-buffer": "^1.1.5" + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, - "node_modules/sane/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true }, - "node_modules/sane/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==", + "node_modules/sh-syntax": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/sh-syntax/-/sh-syntax-0.4.1.tgz", + "integrity": "sha512-MW/ZsCYTu11EIYYTSZcfAgMFszAodCmQVB27XssHoIN6L4EG0KSA3h32x8whaSOKuYBX5wz9EybfnPBUFQMCKA==", "dev": true, + "dependencies": { + "tslib": "^2.6.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" } }, - "node_modules/sane/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "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==", "dev": true, "dependencies": { - "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" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" }, - "engines": { - "node": ">=0.10.0" + "bin": { + "sha.js": "bin.js" } }, - "node_modules/sane/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "node_modules/sharp": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.1.tgz", + "integrity": "sha512-iAYUnOdTqqZDb3QjMneBKINTllCJDZ3em6WaWy7NPECM4aHncvqHRm0v0bN9nqJxMiwamv5KIdauJ6lUzKDpTQ==", "dev": true, + "hasInstallScript": true, "dependencies": { - "remove-trailing-separator": "^1.0.1" + "color": "^4.2.3", + "detect-libc": "^2.0.2", + "semver": "^7.5.4" }, "engines": { - "node": ">=0.10.0" + "libvips": ">=8.15.0", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.1", + "@img/sharp-darwin-x64": "0.33.1", + "@img/sharp-libvips-darwin-arm64": "1.0.0", + "@img/sharp-libvips-darwin-x64": "1.0.0", + "@img/sharp-libvips-linux-arm": "1.0.0", + "@img/sharp-libvips-linux-arm64": "1.0.0", + "@img/sharp-libvips-linux-s390x": "1.0.0", + "@img/sharp-libvips-linux-x64": "1.0.0", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.0", + "@img/sharp-libvips-linuxmusl-x64": "1.0.0", + "@img/sharp-linux-arm": "0.33.1", + "@img/sharp-linux-arm64": "0.33.1", + "@img/sharp-linux-s390x": "0.33.1", + "@img/sharp-linux-x64": "0.33.1", + "@img/sharp-linuxmusl-arm64": "0.33.1", + "@img/sharp-linuxmusl-x64": "0.33.1", + "@img/sharp-wasm32": "0.33.1", + "@img/sharp-win32-ia32": "0.33.1", + "@img/sharp-win32-x64": "0.33.1" } }, - "node_modules/sane/node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "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==", "dev": true, "dependencies": { - "path-key": "^2.0.0" + "shebang-regex": "^3.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/sane/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "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==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/sane/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", "dev": true, - "bin": { - "semver": "bin/semver" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/sane/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "node_modules/shellcheck": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/shellcheck/-/shellcheck-2.2.0.tgz", + "integrity": "sha512-rMt0WhmeqRrKMUqyTlkL6pd0zY27FRQMQWjQhpHMQETwG2ykc8gz+QGGtxHym4R2np646QgQAcq04sAEo3SWhA==", "dev": true, "dependencies": { - "shebang-regex": "^1.0.0" + "decompress": "^4.2.1", + "global-agent": "^3.0.0" + }, + "bin": { + "shellcheck": "bin/shellcheck.js" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/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, - "engines": { - "node": ">=0.10.0" + "node": ">=18.4.0 || >=16.17.0" } }, - "node_modules/sane/node_modules/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=", + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", "dev": true, "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/sane/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "node_modules/shelljs/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "dependencies": { - "isexe": "^2.0.0" + "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" }, - "bin": { - "which": "bin/which" + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/saslprep": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", - "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", + "node_modules/shelljs/node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "dev": true, - "optional": true, - "dependencies": { - "sparse-bitfield": "^3.0.3" - }, "engines": { - "node": ">=6" + "node": ">= 0.10" } }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true - }, - "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "node_modules/shelljs/node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", "dev": true, "dependencies": { - "xmlchars": "^2.2.0" + "resolve": "^1.1.6" }, "engines": { - "node": ">=10" + "node": ">= 0.10" } }, - "node_modules/semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "node_modules/shx": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.4.tgz", + "integrity": "sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==", + "dev": true, "dependencies": { - "lru-cache": "^6.0.0" + "minimist": "^1.2.3", + "shelljs": "^0.8.5" }, "bin": { - "semver": "bin/semver.js" + "shx": "lib/cli.js" }, "engines": { - "node": ">=10" + "node": ">=6" } }, - "node_modules/semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", - "dev": true - }, - "node_modules/semver-greatest-satisfied-range": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", - "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=", + "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==", "dev": true, "dependencies": { - "sver-compat": "^1.5.0" + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" }, - "engines": { - "node": ">= 0.10" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/semver-regex": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.2.tgz", - "integrity": "sha512-bXWyL6EAKOJa81XG1OZ/Yyuq+oT0b2YLlxx7c+mrdYPaPbnj6WgVULXhinMIeZGufuUBu/eVRqXEhiv4imfwxA==", + "node_modules/sift": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz", + "integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==", + "dev": true + }, + "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==", "dev": true, "engines": { - "node": ">=8" + "node": ">=14" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "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==", + "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==", + "dev": true, "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" + "is-arrayish": "^0.3.1" } }, - "node_modules/semver/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/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==", + "dev": true }, - "node_modules/send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "dependencies": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, "engines": { - "node": ">= 0.8.0" + "node": ">=8" } }, - "node_modules/send/node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "node_modules/serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", "dev": true, "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, - "node_modules/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==", + "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==", + "dev": true, + "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==", "dev": true, "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 10.13.0", + "npm": ">= 3.0.0" } }, - "node_modules/set-value/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "node_modules/socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", "dev": true, "dependencies": { - "is-extendable": "^0.1.0" + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" }, "engines": { - "node": ">=0.10.0" + "node": ">= 10" } }, - "node_modules/set-value/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "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/setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", - "dev": true - }, - "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==", + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "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==", + "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==", "dev": true, "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" + "memory-pager": "^1.0.2" } }, - "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==", + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" } }, - "node_modules/shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "dev": true, - "optional": true - }, - "node_modules/sift": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/sift/-/sift-7.0.1.tgz", - "integrity": "sha512-oqD7PMJ+uO6jV9EQCl0LrRw1OwsiPsiFQR5AR30heR+4Dl7jBBbDLnNvWiak20tzZlSE1H7RB30SX/1j/YYT7g==", + "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/signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "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.13", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", + "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", "dev": true }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "node_modules/split-skip": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/split-skip/-/split-skip-0.0.2.tgz", + "integrity": "sha512-weHOi8BolsDnGIwhhWHbA+wKSuSpvWwjRrdj8SdbIIis2vSwOE37CQP8x3EleuzxanUr3AK8BdUy4MkiOULPZg==", "dev": true }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", "dev": true, "engines": { - "node": ">=8" + "node": ">= 10.x" } }, - "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==", + "node_modules/sponsorkit": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/sponsorkit/-/sponsorkit-0.9.1.tgz", + "integrity": "sha512-k6/hg4ASrQSmosB2AjmqG6SSBKYxaalhi4hFD7ZzJNXezO0SMhlxWL1Uk9gvsuQFdHowiCCTgGx0078csm3mog==", "dev": true, "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" + "consola": "^3.2.3", + "dotenv": "^16.3.1", + "fs-extra": "^11.2.0", + "image-data-uri": "^2.0.1", + "node-html-parser": "^6.1.11", + "ofetch": "^1.3.3", + "picocolors": "^1.0.0", + "sharp": "^0.33.0", + "unconfig": "^0.3.11", + "yargs": "^17.7.2" }, - "engines": { - "node": ">=8" + "bin": { + "sponsorkit": "bin/sponsorkit.js" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" } }, - "node_modules/sliced": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", - "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=", + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", "dev": true }, - "node_modules/smart-buffer": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.1.0.tgz", - "integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==", + "node_modules/sqlstring": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", + "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==", "dev": true, "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" + "node": ">= 0.6" } }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "node_modules/sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", "dev": true, "dependencies": { - "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" + "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/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==", + "node_modules/ssri": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.4.tgz", + "integrity": "sha512-12+IR2CB2C28MMAw0Ncqwj5QbTcs0nGIhgJzYWzDkb21vWmfNI83KS4f3Ci6GI98WreIfG7o9UXp3C0qbpA8nQ==", "dev": true, "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" + "minipass": "^5.0.0" }, "engines": { - "node": ">=0.10.0" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "node_modules/ssri/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, "dependencies": { - "kind-of": "^3.2.0" + "escape-string-regexp": "^2.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/snapdragon/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "node_modules/standard-as-callback": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", + "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==", + "dev": true + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8" } }, - "node_modules/snapdragon/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "node_modules/stop-iteration-iterator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", + "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", "dev": true, "dependencies": { - "is-extendable": "^0.1.0" + "internal-slot": "^1.0.4" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, - "node_modules/snapdragon/node_modules/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=", + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, "engines": { - "node": ">=0.10.0" + "node": ">=10.0.0" } }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" + "safe-buffer": "~5.1.0" } }, - "node_modules/snapdragon/node_modules/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=", + "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==", + "dev": true + }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, "engines": { - "node": ">=0.10.0" + "node": ">=0.6.19" } }, - "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, "dependencies": { - "is-buffer": "^1.1.5" + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/snapdragon/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/snapdragon/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "node_modules/string-width-cjs": { + "name": "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, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/snapdragon/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "engines": { - "node": ">=0.10.0" + "node_modules/string-width-cjs/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==", + "dev": true + }, + "node_modules/string-width-cjs/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==", + "dev": true, + "engines": { + "node": ">=8" } }, - "node_modules/socks": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.5.1.tgz", - "integrity": "sha512-oZCsJJxapULAYJaEYBSzMcz8m3jqgGrHaGhkmU/o/PQfFWYWxkAaA0UMGImb6s6tEXfKi959X6VJjMMQ3P6TTQ==", + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, - "dependencies": { - "ip": "^1.1.5", - "smart-buffer": "^4.1.0" - }, "engines": { - "node": ">= 10.13.0", - "npm": ">= 3.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/socks-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz", - "integrity": "sha512-lEpa1zsWCChxiynk+lCycKuC502RxDWLKJZoIhnxrWNjLSDGYRFflHA1/228VkRcnv9TIb8w98derGbpKxJRgA==", + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "dependencies": { - "agent-base": "6", - "debug": "4", - "socks": "^2.3.3" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">= 6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/socks-proxy-agent/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "node_modules/string.prototype.padend": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.4.tgz", + "integrity": "sha512-67otBXoksdjsnXXRUq+KMVTdlVRZ2af422Y0aTyTjVaoQkGr3mxl2Bc5emi7dOQ3OGVVQQskmLEWwFXwommpNw==", "dev": true, "dependencies": { - "ms": "2.1.2" + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" }, "engines": { - "node": ">=6.0" + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/socks-proxy-agent/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "node_modules/string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, "engines": { - "node": ">= 8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/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==", + "node_modules/string.prototype.trimend": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", "dev": true, "dependencies": { - "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" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "node_modules/string.prototype.trimstart": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", "dev": true, "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/source-map-support/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==", + "node_modules/stringify-parameters": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stringify-parameters/-/stringify-parameters-0.0.4.tgz", + "integrity": "sha512-H3L90ERn5UPtkpO8eugnKcLgpIVlvTyUTrcLGm607AV5JDH6z0GymtNLr3gjGlP6I6NB/mxNX9QpY6jEQGLPdQ==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "magicli": "0.0.5", + "unpack-string": "0.0.2" + }, + "bin": { + "stringify-parameters": "bin/cli.js" } }, - "node_modules/source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "node_modules/stringify-parameters/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/sparkles": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", - "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", + "node_modules/stringify-parameters/node_modules/get-stdin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", + "integrity": "sha512-jZV7n6jGE3Gt7fgSTJoz91Ak5MuTLwMwkoYdjxuJ/AmjIsE1UC03y/IWkZCQGEvVNS9qoRNwy5BCqxImv0FVeA==", "dev": true, "engines": { - "node": ">= 0.10" - } - }, - "node_modules/sparse-bitfield": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", - "dev": true, - "optional": true, - "dependencies": { - "memory-pager": "^1.0.2" + "node": ">=0.12.0" } }, - "node_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "node_modules/stringify-parameters/node_modules/inspect-function": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/inspect-function/-/inspect-function-0.2.2.tgz", + "integrity": "sha512-becs5gzcHwPrlHawscYkyQ/ShiOiosrXPhA5RVZ3qyWH4aWdD52RnMfXq/dwQXciHwiieD8aIPwdIWYv6eL+sQ==", "dev": true, "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "split-skip": "0.0.1", + "unpack-string": "0.0.2" } }, - "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==", + "node_modules/stringify-parameters/node_modules/magicli": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/magicli/-/magicli-0.0.5.tgz", + "integrity": "sha512-wZbMtnl2v1b+Jp3xlqA9FU/O4I6YhGXR8xSY/eU2+gDAvut/F+W3gl4qs61iL4LELC7jqSAE6aAD5668EbmQHA==", "dev": true, "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "commander": "^2.9.0", + "get-stdin": "^5.0.1", + "inspect-function": "^0.2.1", + "pipe-functions": "^1.2.0" } }, - "node_modules/spdx-license-ids": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", - "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", + "node_modules/stringify-parameters/node_modules/split-skip": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/split-skip/-/split-skip-0.0.1.tgz", + "integrity": "sha512-7dkvq+gofI4M8zx4iZnEZ3O1s7FP4Y/iaIDHJh5RyWrs8idcPauFi2OZe3TBi36fLvR2j5z3kSzVtz6IhPdncQ==", "dev": true }, - "node_modules/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==", + "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==", "dev": true, "dependencies": { - "extend-shallow": "^3.0.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=0.10.0" - } - }, - "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": ">=8" } }, - "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==", + "node_modules/strip-ansi-cjs": { + "name": "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, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">= 6" + "node": ">=8" } }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "node_modules/sqlstring": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.2.tgz", - "integrity": "sha512-vF4ZbYdKS8OnoJAWBmMxCQDkiEBkGQYU7UZPtL8flbDRSNkhaXvRJ279ZtI6M+zDaQovVU4tuRgzK5fVhvFAhg==", + "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": ">= 0.6" + "node": ">=8" } }, - "node_modules/sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "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": { - "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" - }, - "engines": { - "node": ">=0.10.0" + "is-natural-number": "^4.0.1" } }, - "node_modules/ssri": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.0.tgz", - "integrity": "sha512-aq/pz989nxVYwn16Tsbj1TqFpD5LLrQxHf5zaHuieFV+R0Bbr4y8qUsOA45hXT/N4/9UNXTarBjnjVmjSOVaAA==", + "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, - "dependencies": { - "minipass": "^3.1.1" - }, "engines": { - "node": ">= 8" + "node": ">=6" } }, - "node_modules/stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", + "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==", "dev": true, "engines": { - "node": "*" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "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": { - "escape-string-regexp": "^2.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "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": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/standard-as-callback": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.0.1.tgz", - "integrity": "sha512-NQOxSeB8gOI5WjSaxjBgog2QFw55FV8TkS6Y07BiB3VJ8xNTvUYm0wl0s8ObgQ5NhdpnNfigMIKjgPESzgr4tg==", - "dev": true - }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "node_modules/synckit": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz", + "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==", "dev": true, "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=0.10.0" + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" } }, - "node_modules/static-extend/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "node_modules/table-layout": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz", + "integrity": "sha512-zTvf0mcggrGeTe/2jJ6ECkJHAQPIYEwDoqsiqBjI24mvRmQbInK5jq33fyypaCBxX08hMkfmdOqj6haT33EqWw==", "dev": true, "dependencies": { - "is-descriptor": "^0.1.0" + "array-back": "^2.0.0", + "deep-extend": "~0.6.0", + "lodash.padend": "^4.6.1", + "typical": "^2.6.1", + "wordwrapjs": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=4.0.0" } }, - "node_modules/static-extend/node_modules/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=", + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/tar": { + "version": "6.1.15", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", + "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==", "dev": true, "dependencies": { - "is-buffer": "^1.1.5" + "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": ">=0.10.0" + "node": ">=10" } }, - "node_modules/static-extend/node_modules/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=", + "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": { - "kind-of": "^3.0.2" + "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.10.0" + "node": ">= 0.8.0" } }, - "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/tar/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": { - "is-buffer": "^1.1.5" + "minipass": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 8" } }, - "node_modules/static-extend/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "node_modules/tar/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": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "yallist": "^4.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "node_modules/tar/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": ">= 0.6" + "node": ">=8" } }, - "node_modules/stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "node_modules/tarn": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.2.tgz", + "integrity": "sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8.0.0" } }, - "node_modules/stoppable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", - "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==", + "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": ">=4", - "npm": ">=6" + "node": ">=8" } }, - "node_modules/stream-exhaust": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", - "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", - "dev": true - }, - "node_modules/stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "node_modules/streamsearch": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", - "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=", + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, + "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": ">=0.8.0" + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", "dev": true, "dependencies": { - "safe-buffer": "~5.1.0" + "any-promise": "^1.0.0" } }, - "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==", + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", "dev": true, + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, "engines": { - "node": ">=0.6.19" + "node": ">=0.8" } }, - "node_modules/string-length": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", - "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==", + "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/tildify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz", + "integrity": "sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==", "dev": true, - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "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==", "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "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": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "is-number": "^7.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=8.0" } }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "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==", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=0.6" } }, - "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==", + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, "dependencies": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" + "psl": "^1.1.28", + "punycode": "^2.1.1" }, "engines": { - "node": ">=4" + "node": ">=0.8" } }, - "node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "ansi-regex": "^5.0.0" + "punycode": "^2.1.1" }, "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "node_modules/ts-api-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz", + "integrity": "sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==", "dev": true, "engines": { - "node": ">=8" + "node": ">=16.13.0" + }, + "peerDependencies": { + "typescript": ">=4.2.0" } }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "node_modules/ts-graphviz": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/ts-graphviz/-/ts-graphviz-1.8.1.tgz", + "integrity": "sha512-54/fe5iu0Jb6X0pmDmzsA2UHLfyHjUEUwfHtZcEOR0fZ6Myf+dFoO6eNsyL8CBDMJ9u7WWEewduVaiaXlvjSVw==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ts-graphviz" } }, - "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==", + "node_modules/ts-jest": { + "version": "29.1.1", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz", + "integrity": "sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==", "dev": true, + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "^7.5.3", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, "engines": { - "node": ">=6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } } }, - "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==", + "node_modules/ts-jest/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": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/subscriptions-transport-ws": { - "version": "0.9.18", - "resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.18.tgz", - "integrity": "sha512-tztzcBTNoEbuErsVQpTN2xUNN/efAZXyCyL5m3x4t6SKrEiTL2N8SaKWBFWM4u56pL79ULif3zjyeq+oV+nOaA==", - "dev": true, - "dependencies": { - "backo2": "^1.0.2", - "eventemitter3": "^3.1.0", - "iterall": "^1.2.1", - "symbol-observable": "^1.0.4", - "ws": "^5.2.0" + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" }, "peerDependencies": { - "graphql": ">=0.10.0" + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } } }, - "node_modules/subscriptions-transport-ws/node_modules/ws": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", - "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "node_modules/ts-patch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/ts-patch/-/ts-patch-3.1.1.tgz", + "integrity": "sha512-ReGYz9jQYC80PFafBx25TC0UI9cSgmUBtpT+WIy8IrhpLVzEHf430k03XQYOMldQMyZDBbzn5fBPELgtIl65cA==", "dev": true, "dependencies": { - "async-limiter": "~1.0.0" + "chalk": "^4.1.2", + "global-prefix": "^3.0.0", + "minimist": "^1.2.8", + "resolve": "^1.22.2", + "semver": "^7.5.4", + "strip-ansi": "^6.0.1" + }, + "bin": { + "ts-patch": "bin/ts-patch.js", + "tspc": "bin/tspc.js" } }, - "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==", + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/supports-hyperlinks": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", - "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", + "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, - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/sver-compat": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", - "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=", - "dev": true, - "dependencies": { - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" - } + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, - "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==", + "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": ">=0.10.0" + "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/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "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/tar": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.5.tgz", - "integrity": "sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg==", + "node_modules/tsyringe": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/tsyringe/-/tsyringe-4.8.0.tgz", + "integrity": "sha512-YB1FG+axdxADa3ncEtRnQCFq/M0lALGLxSZeVNbTU8NqhOVc51nnv2CISTcvc1kyv6EGPtXVr0v6lWeDxiijOA==", "dev": true, "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" + "tslib": "^1.9.3" }, "engines": { - "node": ">= 10" + "node": ">= 6.0.0" } }, - "node_modules/tar/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/tsyringe/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/tarn": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.1.tgz", - "integrity": "sha512-6usSlV9KyHsspvwu2duKH+FMUhqJnAh6J5J/4MITl8s94iSUQTLkJggdiewKv4RyARQccnigV48Z+khiuVZDJw==", + "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==", "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, "engines": { - "node": ">=8.0.0" + "node": "*" } }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" + "prelude-ls": "^1.2.1" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.8.0" } }, - "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==", + "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==", "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/textextensions": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-2.6.0.tgz", - "integrity": "sha512-49WtAWS+tcsy93dRt6P0P3AMD2m5PvXRhuEA0kaXos5ZLlujtYmpmFsB+QvWUSxE1ZsstmYXfQ7L40+EcQgpAQ==", + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, "engines": { - "node": ">=0.8" + "node": ">=10" }, "funding": { - "url": "https://bevry.me/fund" - } - }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", - "dev": true, - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/throat": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", - "dev": true - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "node_modules/through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - }, - "node_modules/through2-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", - "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", - "dev": true, - "dependencies": { - "through2": "~2.0.0", - "xtend": "~4.0.0" - } - }, - "node_modules/through2-filter/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/tildify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz", - "integrity": "sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/time-stamp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tmpl": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", - "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", - "dev": true - }, - "node_modules/to-absolute-glob": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", - "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", - "dev": true, - "dependencies": { - "is-absolute": "^1.0.0", - "is-negated-glob": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/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, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "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==", "dev": true, "dependencies": { - "is-buffer": "^1.1.5" + "media-typer": "0.3.0", + "mime-types": "~2.1.24" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.6" } }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "node_modules/typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", "dev": true, "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.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==", + "node_modules/typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", "dev": true, "dependencies": { - "is-number": "^7.0.0" + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" }, "engines": { - "node": ">=8.0" - } - }, - "node_modules/to-through": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", - "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", - "dev": true, - "dependencies": { - "through2": "^2.0.3" + "node": ">= 0.4" }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/to-through/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" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/toidentifier": { + "node_modules/typed-array-byte-offset": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tough-cookie": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", - "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", "dev": true, "dependencies": { - "ip-regex": "^2.1.0", - "psl": "^1.1.28", - "punycode": "^2.1.1" + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" }, "engines": { - "node": ">=6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/tr46": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", - "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", + "node_modules/typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", "dev": true, "dependencies": { - "punycode": "^2.1.1" + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ts-invariant": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.4.4.tgz", - "integrity": "sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==", + "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": { - "tslib": "^1.9.3" + "is-typedarray": "^1.0.0" } }, - "node_modules/ts-invariant/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "node_modules/typedi": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/typedi/-/typedi-0.10.0.tgz", + "integrity": "sha512-v3UJF8xm68BBj6AF4oQML3ikrfK2c9EmZUyLOfShpJuItAqVBHWP/KtpGinkSsIiP6EZyyb6Z3NXyW9dgS9X1w==", "dev": true }, - "node_modules/ts-jest": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.2.tgz", - "integrity": "sha512-bwyJ2zJieSugf7RB+o8fgkMeoMVMM2KPDE0UklRLuACxjwJsOrZNo6chrcScmK33YavPSwhARffy8dZx5LJdUQ==", - "dev": true, - "dependencies": { - "@types/jest": "26.x", - "bs-logger": "0.x", - "buffer-from": "1.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^26.1.0", - "json5": "2.x", - "lodash": "4.x", - "make-error": "1.x", - "mkdirp": "1.x", - "semver": "7.x", - "yargs-parser": "20.x" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": ">= 10" - }, - "peerDependencies": { - "jest": ">=26 <27", - "typescript": ">=3.8 <5.0" - } - }, - "node_modules/ts-node": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", - "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", - "dev": true, - "dependencies": { - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.17", - "yn": "3.1.1" + "node_modules/typeorm": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.19.tgz", + "integrity": "sha512-OGelrY5qEoAU80mR1iyvmUHiKCPUydL6xp6bebXzS7jyv/X70Gp/jBWRAfF4qGOfy2A7orMiGRfwsBUNbEL65g==", + "dev": true, + "dependencies": { + "@sqltools/formatter": "^1.2.5", + "app-root-path": "^3.1.0", + "buffer": "^6.0.3", + "chalk": "^4.1.2", + "cli-highlight": "^2.1.11", + "dayjs": "^1.11.9", + "debug": "^4.3.4", + "dotenv": "^16.0.3", + "glob": "^10.3.10", + "mkdirp": "^2.1.3", + "reflect-metadata": "^0.1.13", + "sha.js": "^2.4.11", + "tslib": "^2.5.0", + "uuid": "^9.0.0", + "yargs": "^17.6.2" }, "bin": { - "ts-node": "dist/bin.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" + "typeorm": "cli.js", + "typeorm-ts-node-commonjs": "cli-ts-node-commonjs.js", + "typeorm-ts-node-esm": "cli-ts-node-esm.js" }, "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "typescript": ">=2.7" - } - }, - "node_modules/tslib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", - "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==" - }, - "node_modules/tslint": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", - "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", - "deprecated": "TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information.", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^4.0.1", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.3", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.13.0", - "tsutils": "^2.29.0" - }, - "bin": { - "tslint": "bin/tslint" + "node": ">= 12.9.0" }, - "engines": { - "node": ">=4.8.0" + "funding": { + "url": "https://opencollective.com/typeorm" }, "peerDependencies": { - "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 4.0.0-dev" - } - }, - "node_modules/tslint-config-prettier": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", - "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", - "dev": true, - "bin": { - "tslint-config-prettier-check": "bin/check.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/tslint-eslint-rules": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/tslint-eslint-rules/-/tslint-eslint-rules-5.4.0.tgz", - "integrity": "sha512-WlSXE+J2vY/VPgIcqQuijMQiel+UtmXS+4nvK4ZzlDiqBfXse8FAvkNnTcYhnQyOTW5KFM+uRRGXxYhFpuBc6w==", - "dev": true, - "dependencies": { - "doctrine": "0.7.2", - "tslib": "1.9.0", - "tsutils": "^3.0.0" + "@google-cloud/spanner": "^5.18.0", + "@sap/hana-client": "^2.12.25", + "better-sqlite3": "^7.1.2 || ^8.0.0 || ^9.0.0", + "hdb-pool": "^0.1.6", + "ioredis": "^5.0.4", + "mongodb": "^5.8.0", + "mssql": "^9.1.1 || ^10.0.1", + "mysql2": "^2.2.5 || ^3.0.1", + "oracledb": "^6.3.0", + "pg": "^8.5.1", + "pg-native": "^3.0.0", + "pg-query-stream": "^4.0.0", + "redis": "^3.1.1 || ^4.0.0", + "sql.js": "^1.4.0", + "sqlite3": "^5.0.3", + "ts-node": "^10.7.0", + "typeorm-aurora-data-api-driver": "^2.0.0" }, - "peerDependencies": { - "tslint": "^5.0.0", - "typescript": "^2.2.0 || ^3.0.0" - } - }, - "node_modules/tslint-eslint-rules/node_modules/tslib": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz", - "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ==", - "dev": true - }, - "node_modules/tslint-eslint-rules/node_modules/tsutils": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.20.0.tgz", - "integrity": "sha512-RYbuQuvkhuqVeXweWT3tJLKOEJ/UUw9GjNEZGWdrLLlM+611o1gwLHBpxoFJKKl25fLprp2eVthtKs5JOrNeXg==", - "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/tslint/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tslint/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tslint/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/tslint/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/tslint/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/tslint/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/tslint/node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/tslint/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/tslint/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==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tslint/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/tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "peerDependencies": { - "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" - } - }, - "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-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, - "node_modules/type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true - }, - "node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "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==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", - "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "dev": true, - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "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/typedi": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/typedi/-/typedi-0.10.0.tgz", - "integrity": "sha512-v3UJF8xm68BBj6AF4oQML3ikrfK2c9EmZUyLOfShpJuItAqVBHWP/KtpGinkSsIiP6EZyyb6Z3NXyW9dgS9X1w==", - "dev": true - }, - "node_modules/typeorm": { - "version": "0.2.31", - "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.2.31.tgz", - "integrity": "sha512-dVvCEVHH48DG0QPXAKfo0l6ecQrl3A8ucGP4Yw4myz4YEDMProebTQo8as83uyES+nrwCbu3qdkL4ncC2+qcMA==", - "dev": true, - "dependencies": { - "@sqltools/formatter": "1.2.2", - "app-root-path": "^3.0.0", - "buffer": "^5.5.0", - "chalk": "^4.1.0", - "cli-highlight": "^2.1.10", - "debug": "^4.1.1", - "dotenv": "^8.2.0", - "glob": "^7.1.6", - "js-yaml": "^3.14.0", - "mkdirp": "^1.0.4", - "reflect-metadata": "^0.1.13", - "sha.js": "^2.4.11", - "tslib": "^1.13.0", - "xml2js": "^0.4.23", - "yargonaut": "^1.1.2", - "yargs": "^16.0.3" - }, - "bin": { - "typeorm": "cli.js" - }, - "funding": { - "url": "https://opencollective.com/typeorm" - } - }, - "node_modules/typeorm-typedi-extensions": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/typeorm-typedi-extensions/-/typeorm-typedi-extensions-0.4.1.tgz", - "integrity": "sha512-05hWktQ4zuXzTTUO3ao56yOezlvUuZhH2NRS//m0SOGCAJoVlfPTMHcmDaMSQy/lMfAwPWoIyn+sfK7ONzTdXQ==", - "dev": true, - "peerDependencies": { - "typedi": ">=0.10.0", - "typeorm": ">=0.2.30" - } - }, - "node_modules/typeorm/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "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/typeorm/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/typeorm/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/typeorm/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==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/typeorm/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/typeorm/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/typeorm/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/typeorm/node_modules/y18n": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", - "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/typeorm/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/typescript": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.2.tgz", - "integrity": "sha512-tbb+NVrLfnsJy3M59lsDgrzWIflR4d4TIUjz+heUnHZwdF7YsrMTKoRERiIvI2lvBG95dfpLxB21WZhys1bgaQ==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/undertaker": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.3.0.tgz", - "integrity": "sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg==", - "dev": true, - "dependencies": { - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "bach": "^1.0.0", - "collection-map": "^1.0.0", - "es6-weak-map": "^2.0.1", - "fast-levenshtein": "^1.0.0", - "last-run": "^1.1.0", - "object.defaults": "^1.0.0", - "object.reduce": "^1.0.0", - "undertaker-registry": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/undertaker-registry": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", - "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/undertaker/node_modules/fast-levenshtein": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz", - "integrity": "sha1-5qdUzI8V5YmHqpy9J69m/W9OWvk=", - "dev": true - }, - "node_modules/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, - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/union-value/node_modules/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "dependencies": { - "unique-slug": "^2.0.0" - } - }, - "node_modules/unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4" - } - }, - "node_modules/unique-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", - "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", - "dev": true, - "dependencies": { - "json-stable-stringify-without-jsonify": "^1.0.1", - "through2-filter": "^3.0.0" - } - }, - "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": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/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, - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/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, - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true, - "engines": { - "node": ">=4", - "yarn": "*" - } - }, - "node_modules/uri-js": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", - "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "deprecated": "Please see https://github.com/lydell/urix#deprecated", - "dev": true - }, - "node_modules/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "node_modules/util.promisify": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.1.1.tgz", - "integrity": "sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "for-each": "^0.3.3", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, - "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/v8-to-istanbul": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.0.tgz", - "integrity": "sha512-uXUVqNUCLa0AH1vuVxzi+MI4RfxEOKt9pBgKwHbgH7st8Kv2P1m+jvWNnektzBh5QShF3ODgKmUFCf38LnVz1g==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/v8flags": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", - "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", - "dev": true, - "dependencies": { - "homedir-polyfill": "^1.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/valid-url": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", - "integrity": "sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA=", - "dev": true - }, - "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/validator": { - "version": "13.5.2", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.5.2.tgz", - "integrity": "sha512-mD45p0rvHVBlY2Zuy3F3ESIe1h5X58GPfAtslBjY7EtTqGquZTj+VX/J4RnHWN8FKq0C9WRVt1oWAcytWRuYLQ==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/value-or-function": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", - "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/vinyl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", - "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", - "dev": true, - "dependencies": { - "clone": "^2.1.1", - "clone-buffer": "^1.0.0", - "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/vinyl-fs": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", - "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", - "dev": true, - "dependencies": { - "fs-mkdirp-stream": "^1.0.0", - "glob-stream": "^6.1.0", - "graceful-fs": "^4.0.0", - "is-valid-glob": "^1.0.0", - "lazystream": "^1.0.0", - "lead": "^1.0.0", - "object.assign": "^4.0.4", - "pumpify": "^1.3.5", - "readable-stream": "^2.3.3", - "remove-bom-buffer": "^3.0.0", - "remove-bom-stream": "^1.2.0", - "resolve-options": "^1.1.0", - "through2": "^2.0.0", - "to-through": "^2.0.0", - "value-or-function": "^3.0.0", - "vinyl": "^2.0.0", - "vinyl-sourcemap": "^1.1.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/vinyl-fs/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/vinyl-sourcemap": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", - "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", - "dev": true, - "dependencies": { - "append-buffer": "^1.0.2", - "convert-source-map": "^1.5.0", - "graceful-fs": "^4.1.6", - "normalize-path": "^2.1.1", - "now-and-later": "^2.0.0", - "remove-bom-buffer": "^3.0.0", - "vinyl": "^2.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/vinyl-sourcemap/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dev": true, - "dependencies": { - "browser-process-hrtime": "^1.0.0" - } - }, - "node_modules/w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "dependencies": { - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/walker": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", - "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", - "dev": true, - "dependencies": { - "makeerror": "1.0.x" - } - }, - "node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true, - "engines": { - "node": ">=10.4" - } - }, - "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "dependencies": { - "iconv-lite": "0.4.24" - } - }, - "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true - }, - "node_modules/whatwg-url": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.4.0.tgz", - "integrity": "sha512-vwTUFf6V4zhcPkWp/4CQPr1TW9Ml6SF4lVyaIMBdJw5i6qUUJ1QWM4Z6YYVkfka0OUIzVo/0aNtGVGk256IKWw==", - "dev": true, - "dependencies": { - "lodash.sortby": "^4.7.0", - "tr46": "^2.0.2", - "webidl-conversions": "^6.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", - "dev": true - }, - "node_modules/which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", - "dev": true - }, - "node_modules/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, - "engines": { - "node": ">=0.10.0" - } - }, - "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/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "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": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", - "dev": true, - "dependencies": { - "async-limiter": "~1.0.0" - } - }, - "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true - }, - "node_modules/xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "dev": true, - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true - }, - "node_modules/xss": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.8.tgz", - "integrity": "sha512-3MgPdaXV8rfQ/pNn16Eio6VXYPTkqwa0vc7GkiymmY/DqR1SE/7VPAAVZz1GJsJFrllMYO3RHfEaiUGjab6TNw==", - "dev": true, - "dependencies": { - "commander": "^2.20.3", - "cssfilter": "0.0.10" - }, - "bin": { - "xss": "bin/xss" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/xss/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "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/yargonaut": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/yargonaut/-/yargonaut-1.1.4.tgz", - "integrity": "sha512-rHgFmbgXAAzl+1nngqOcwEljqHGG9uUZoPjsdZEs1w5JW9RXYzrSvH/u70C1JE5qFi0qjsdhnUX/dJRpWqitSA==", - "dev": true, - "dependencies": { - "chalk": "^1.1.1", - "figlet": "^1.1.1", - "parent-require": "^1.0.0" - } - }, - "node_modules/yargonaut/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yargonaut/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yargonaut/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yargonaut/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yargonaut/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/yargs": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.1.tgz", - "integrity": "sha512-huO4Fr1f9PmiJJdll5kwoS2e4GqzGSsMT3PPMpOwoVkOK8ckqAewMTZyA6LXVQWflleb/Z8oPBEvNsMft0XE+g==", - "dev": true, - "dependencies": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "y18n": "^3.2.1", - "yargs-parser": "5.0.0-security.0" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.6", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.6.tgz", - "integrity": "sha512-AP1+fQIWSM/sMiET8fyayjx/J+JmTPt2Mr0FkrgqB4todtfa53sOsrSAcIrJRD5XS20bKUwaDIuMkWKCEiQLKA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yargs/node_modules/camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yargs/node_modules/find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "dependencies": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yargs/node_modules/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=", - "dev": true, - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yargs/node_modules/path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "dependencies": { - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yargs/node_modules/path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yargs/node_modules/read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "dependencies": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yargs/node_modules/read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "dependencies": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "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/yargs/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "5.0.0-security.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0-security.0.tgz", - "integrity": "sha512-T69y4Ps64LNesYxeYGYPvfoMTt/7y1XtfpIslUeK4um+9Hu7hlGoRtaDLvdXb7+/tfq4opVa2HRY5xGip022rQ==", - "dev": true, - "dependencies": { - "camelcase": "^3.0.0", - "object.assign": "^4.1.0" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "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": "0.8.21", - "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.8.21.tgz", - "integrity": "sha512-Yj3yXweRc8LdRMrCC8nIc4kkjWecPAUVh0TI0OUrWXx6aX790vLcDlWca6I4vsyCGH3LpWxq0dJRcMOFoVqmeg==", - "dev": true, - "dependencies": { - "tslib": "^1.9.3", - "zen-observable": "^0.8.0" - } - }, - "node_modules/zen-observable-ts/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 - } - }, - "dependencies": { - "@apollo/federation": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/@apollo/federation/-/federation-0.21.2.tgz", - "integrity": "sha512-ZQ2TcRv7QO/84+SKFQrhppg+s0EcwBfSPT27DcoLYfEj8tsNjbUmsyxiH5CE2NJtG0F8y520nIM8tQ9wUrePsg==", - "dev": true, - "requires": { - "apollo-graphql": "^0.6.0", - "lodash.xorby": "^4.7.0" - } - }, - "@apollo/gateway": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/@apollo/gateway/-/gateway-0.23.2.tgz", - "integrity": "sha512-WGrlAzvBfvWGnwajlUowde2VXdkH5EtqgOLnwdYCB7FVMkLT8B/Qj6ePxK+Kbwonz7lcnEvNaL4rvF2ICGudWg==", - "dev": true, - "requires": { - "@apollo/federation": "^0.21.2", - "@apollo/query-planner-wasm": "^0.1.2", - "@types/node-fetch": "2.5.4", - "apollo-graphql": "^0.6.0", - "apollo-reporting-protobuf": "^0.6.0", - "apollo-server-caching": "^0.5.3", - "apollo-server-core": "^2.19.2", - "apollo-server-env": "^3.0.0", - "apollo-server-errors": "^2.4.2", - "apollo-server-types": "^0.6.3", - "loglevel": "^1.6.1", - "make-fetch-happen": "^8.0.0", - "pretty-format": "^26.0.0" - } - }, - "@apollo/protobufjs": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.0.5.tgz", - "integrity": "sha512-ZtyaBH1icCgqwIGb3zrtopV2D5Q8yxibkJzlaViM08eOhTQc7rACdYu0pfORFfhllvdMZ3aq69vifYHszY4gNA==", - "dev": 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/long": "^4.0.0", - "@types/node": "^10.1.0", - "long": "^4.0.0" - }, - "dependencies": { - "@types/node": { - "version": "10.17.54", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.54.tgz", - "integrity": "sha512-c8Lm7+hXdSPmWH4B9z/P/xIXhFK3mCQin4yCYMd2p1qpMG5AfgyJuYZ+3q2dT7qLiMMMGMd5dnkFpdqJARlvtQ==", - "dev": true - } - } - }, - "@apollo/query-planner-wasm": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@apollo/query-planner-wasm/-/query-planner-wasm-0.1.2.tgz", - "integrity": "sha512-djHcJXTOEZZec0M8ZhK3rGu/ZEAilgr6mu55X7JIxEJEI7Sq57e4r4Lbsfffx+fVxjDb2BK4mabsPHR4vVnG0Q==", - "dev": true - }, - "@apollographql/apollo-tools": { - "version": "0.4.9", - "resolved": "https://registry.npmjs.org/@apollographql/apollo-tools/-/apollo-tools-0.4.9.tgz", - "integrity": "sha512-M50pk8oo3CGTu4waGOklIX3YtTZoPfWG9K/G9WB8NpyQGA1OwYTiBFv94XqUtKElTDoFwoMXpMQd3Wy5dINvxA==", - "dev": true, - "requires": { - "apollo-env": "^0.6.6" - } - }, - "@apollographql/graphql-playground-html": { - "version": "1.6.26", - "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.26.tgz", - "integrity": "sha512-XAwXOIab51QyhBxnxySdK3nuMEUohhDsHQ5Rbco/V1vjlP75zZ0ZLHD9dTpXTN8uxKxopb2lUvJTq+M4g2Q0HQ==", - "dev": true, - "requires": { - "xss": "^1.0.6" - } - }, - "@apollographql/graphql-upload-8-fork": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/@apollographql/graphql-upload-8-fork/-/graphql-upload-8-fork-8.1.3.tgz", - "integrity": "sha512-ssOPUT7euLqDXcdVv3Qs4LoL4BPtfermW1IOouaqEmj36TpHYDmYDIbKoSQxikd9vtMumFnP87OybH7sC9fJ6g==", - "dev": true, - "requires": { - "@types/express": "*", - "@types/fs-capacitor": "*", - "@types/koa": "*", - "busboy": "^0.3.1", - "fs-capacitor": "^2.0.4", - "http-errors": "^1.7.3", - "object-path": "^0.11.4" - } - }, - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/core": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.10.tgz", - "integrity": "sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.10", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helpers": "^7.12.5", - "@babel/parser": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.10", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.19", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "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 - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", - "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", - "dev": true, - "requires": { - "@babel/types": "^7.12.11", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/helper-function-name": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", - "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/types": "^7.12.11" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", - "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", - "dev": true, - "requires": { - "@babel/types": "^7.12.10" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", - "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", - "dev": true, - "requires": { - "@babel/types": "^7.12.7" - } - }, - "@babel/helper-module-imports": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", - "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", - "dev": true, - "requires": { - "@babel/types": "^7.12.5" - } - }, - "@babel/helper-module-transforms": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", - "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.12.1", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-simple-access": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/helper-validator-identifier": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.1", - "@babel/types": "^7.12.1", - "lodash": "^4.17.19" - }, - "dependencies": { - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - } - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", - "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", - "dev": true, - "requires": { - "@babel/types": "^7.12.10" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", - "dev": true - }, - "@babel/helper-replace-supers": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", - "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.12.7", - "@babel/helper-optimise-call-expression": "^7.12.10", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.11" - } - }, - "@babel/helper-simple-access": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", - "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", - "dev": true, - "requires": { - "@babel/types": "^7.12.1" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", - "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", - "dev": true, - "requires": { - "@babel/types": "^7.12.11" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true - }, - "@babel/helpers": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", - "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", - "dev": true, - "requires": { - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.5", - "@babel/types": "^7.12.5" - } - }, - "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", - "dev": true - }, - "@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.8.0" - } - }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz", - "integrity": "sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@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.10.4" - } - }, - "@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, - "requires": { - "@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", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-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, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz", - "integrity": "sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/template": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", - "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.12.7", - "@babel/types": "^7.12.7" - } - }, - "@babel/traverse": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", - "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.11", - "@babel/generator": "^7.12.11", - "@babel/helper-function-name": "^7.12.11", - "@babel/helper-split-export-declaration": "^7.12.11", - "@babel/parser": "^7.12.11", - "@babel/types": "^7.12.12", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.19" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - }, - "dependencies": { - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - } - } - }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "@cnakazawa/watch": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", - "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", - "dev": true, - "requires": { - "exec-sh": "^0.3.2", - "minimist": "^1.2.0" - } - }, - "@graphql-modules/core": { - "version": "0.7.13", - "resolved": "https://registry.npmjs.org/@graphql-modules/core/-/core-0.7.13.tgz", - "integrity": "sha512-csBpOPmk5UdETC5UeN8wqacNMzOrfiMkdEUMixPuQ7/+i0wrvNR1k4FGy97DVb09YGrNhpwF3pphlc/2warhLQ==", - "dev": true, - "requires": { - "@graphql-modules/di": "0.7.13", - "apollo-server-caching": "0.5.0", - "graphql-toolkit": "0.5.16", - "tslib": "1.10.0" - }, - "dependencies": { - "@graphql-modules/di": { - "version": "0.7.13", - "resolved": "https://registry.npmjs.org/@graphql-modules/di/-/di-0.7.13.tgz", - "integrity": "sha512-/WEFjDcrSnXfUS1IA8FwAnI+KQSB5FoBYYlvSQ6hUzD5WYk0Ge34Xt2JVUAlhmRDlgpHlErlFLW6ZhTsKA22/Q==", - "dev": true, - "requires": { - "events": "3.0.0", - "tslib": "1.10.0" - } - }, - "@kamilkisiela/graphql-tools": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@kamilkisiela/graphql-tools/-/graphql-tools-4.0.6.tgz", - "integrity": "sha512-IPWa+dOFCE4zaCsrJrAMp7yWXnfOZLNhqoMEOmn958WkLM0mmsDc/W/Rh7/7xopIT6P0oizb6/N1iH5HnNXOUA==", - "dev": true, - "requires": { - "apollo-link": "^1.2.3", - "apollo-utilities": "^1.0.1", - "deprecated-decorator": "^0.1.6", - "iterall": "^1.1.3", - "uuid": "^3.1.0" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "apollo-server-caching": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.5.0.tgz", - "integrity": "sha512-l7ieNCGxUaUAVAAp600HjbUJxVaxjJygtPV0tPTe1Q3HkPy6LEWoY6mNHV7T268g1hxtPTxcdRu7WLsJrg7ufw==", - "dev": true, - "requires": { - "lru-cache": "^5.0.0" - } - }, - "deepmerge": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.0.0.tgz", - "integrity": "sha512-YZ1rOP5+kHor4hMAH+HRQnBQHg+wvS1un1hAOuIcxcBy0hzcUf6Jg2a1w65kpoOUnurOfZbERwjI1TfZxNjcww==", - "dev": true - }, - "events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", - "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", - "dev": true - }, - "globby": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz", - "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - } - }, - "graphql-import": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/graphql-import/-/graphql-import-0.7.1.tgz", - "integrity": "sha512-YpwpaPjRUVlw2SN3OPljpWbVRWAhMAyfSba5U47qGMOSsPLi2gYeJtngGpymjm9nk57RFWEpjqwh4+dpYuFAPw==", - "dev": true, - "requires": { - "lodash": "^4.17.4", - "resolve-from": "^4.0.0" - }, - "dependencies": { - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - } - } - }, - "graphql-toolkit": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/graphql-toolkit/-/graphql-toolkit-0.5.16.tgz", - "integrity": "sha512-J3rAlsO7A/TJTZ7kLcFYy4/sIvB2AxiosxXFQICdsXf8R9b//fy7jmXnNo38ml1mm//915V0U5HMuAvo/hYiWQ==", - "dev": true, - "requires": { - "@kamilkisiela/graphql-tools": "4.0.6", - "@types/glob": "7.1.1", - "aggregate-error": "3.0.0", - "asyncro": "^3.0.0", - "cross-fetch": "^3.0.4", - "deepmerge": "4.0.0", - "globby": "10.0.1", - "graphql-import": "0.7.1", - "is-glob": "4.0.1", - "is-valid-path": "0.1.1", - "lodash": "4.17.15", - "tslib": "^1.9.3", - "valid-url": "1.0.9" - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - } - } - }, - "@graphql-modules/di": { - "version": "0.7.17", - "resolved": "https://registry.npmjs.org/@graphql-modules/di/-/di-0.7.17.tgz", - "integrity": "sha512-Lq5sd/3RO+bNb8wVnAg43LWbwrqD57D0AVEqZlqiTwUj1f0mITtQdGMRN7g2sG79U7ngoaQx8VK/IiKh8E1OFQ==", - "dev": true, - "requires": { - "events": "3.1.0", - "tslib": "2.0.0" - }, - "dependencies": { - "tslib": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", - "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==", - "dev": true - } - } - }, - "@hapi/hoek": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.1.1.tgz", - "integrity": "sha512-CAEbWH7OIur6jEOzaai83jq3FmKmv4PmX1JYfs9IrYcGEVI/lyL1EXJGCj7eFVJ0bg5QR8LMxBlEtA+xKiLpFw==", - "dev": true - }, - "@hapi/topo": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz", - "integrity": "sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==", - "dev": true, - "requires": { - "@hapi/hoek": "^9.0.0" - } - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "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 - } - } - }, - "@istanbuljs/schema": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", - "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", - "dev": true - }, - "@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "@jest/core": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", - "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", - "dev": true, - "requires": { - "@jest/console": "^26.6.2", - "@jest/reporters": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.6.2", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-resolve-dependencies": "^26.6.3", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "jest-watcher": "^26.6.2", - "micromatch": "^4.0.2", - "p-each-series": "^2.1.0", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" - } - }, - "@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - } - }, - "@jest/globals": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", - "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", - "dev": true, - "requires": { - "@jest/environment": "^26.6.2", - "@jest/types": "^26.6.2", - "expect": "^26.6.2" - } - }, - "@jest/reporters": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", - "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "node-notifier": "^8.0.0", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^7.0.0" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "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 - } - } - }, - "@jest/source-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", - "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", - "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" - }, - "dependencies": { - "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 - } - } - }, - "@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", - "dev": true, - "requires": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", - "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", - "dev": true, - "requires": { - "@jest/test-result": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3" - } - }, - "@jest/transform": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", - "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^26.6.2", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-util": "^26.6.2", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "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 - } - } - }, - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "@mikro-orm/core": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/@mikro-orm/core/-/core-4.4.4.tgz", - "integrity": "sha512-oCFB9cGdJzgPum4rSB9N5py9fODIe7UPxWGBbEhGZnf4bcHrGpsO44WS3aSycypnQ3Lb8oqbge++pAIWQi7JlA==", - "dev": true, - "requires": { - "ansi-colors": "4.1.1", - "clone": "2.1.2", - "escaya": "0.0.61", - "fs-extra": "9.1.0", - "globby": "11.0.2", - "reflect-metadata": "0.1.13", - "strip-json-comments": "3.1.1" - } - }, - "@mikro-orm/knex": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/@mikro-orm/knex/-/knex-4.4.4.tgz", - "integrity": "sha512-dJVL1aURd17qmWsodJgyf9EQ2dyNwV4feAQzAgtwDD+OYapGaMfzKFMn5fomcQpE/IclMPwBxx07l43L275jtg==", - "dev": true, - "requires": { - "fs-extra": "9.1.0", - "knex": "0.21.17", - "sqlstring": "2.3.2" - } - }, - "@mikro-orm/postgresql": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/@mikro-orm/postgresql/-/postgresql-4.4.4.tgz", - "integrity": "sha512-o30y5yopqmgyJltRLKoRi1xz/p67Mu1PvQkV2v10Lk/MhfxvxUQWi7Vn10zOucwKMM57ZjFY/dZUNwEzxoYNHw==", - "dev": true, - "requires": { - "@mikro-orm/knex": "^4.4.4", - "pg": "8.5.1" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", - "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.4", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", - "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", - "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.4", - "fastq": "^1.6.0" - } - }, - "@npmcli/move-file": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.0.1.tgz", - "integrity": "sha512-Uv6h1sT+0DrblvIrolFtbvM1FgWm+/sy4B3pvLp67Zys+thcukzS5ekn7HsZFGpWP4Q3fYJCljbWQE/XivMRLw==", - "dev": true, - "requires": { - "mkdirp": "^1.0.4" - } - }, - "@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=", - "dev": true - }, - "@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "dev": true - }, - "@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "dev": true - }, - "@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=", - "dev": true - }, - "@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", - "dev": true, - "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": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=", - "dev": true - }, - "@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=", - "dev": true - }, - "@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=", - "dev": true - }, - "@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=", - "dev": true - }, - "@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", - "dev": true - }, - "@sideway/address": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.1.tgz", - "integrity": "sha512-+I5aaQr3m0OAmMr7RQ3fR9zx55sejEYR2BFJaxL+zT3VM2611X0SHvPWIbAUBZVTn/YzYKbV8gJ2oT/QELknfQ==", - "dev": true, - "requires": { - "@hapi/hoek": "^9.0.0" - } - }, - "@sideway/formula": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz", - "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==", - "dev": true - }, - "@sideway/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", - "dev": true - }, - "@sinonjs/commons": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", - "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", - "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "@sqltools/formatter": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.2.tgz", - "integrity": "sha512-/5O7Fq6Vnv8L6ucmPjaWbVG1XkP4FO+w5glqfkIsq3Xw4oyNAdJddbnYodNDAfjVUvo/rrSCTom4kAND7T1o5Q==", - "dev": true - }, - "@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 - }, - "@typegoose/typegoose": { - "version": "7.4.8", - "resolved": "https://registry.npmjs.org/@typegoose/typegoose/-/typegoose-7.4.8.tgz", - "integrity": "sha512-fMd+RfyX9e9cCt2P5arh4q3hJtd/emHkjiES0VEIgtOH/XRF7av7ZuktRIEn/KO51H5MSEo9H+Xok6oK+nT7zw==", - "dev": true, - "requires": { - "lodash": "^4.17.20", - "loglevel": "^1.7.0", - "reflect-metadata": "^0.1.13", - "semver": "^7.3.2", - "tslib": "^2.0.1" - }, - "dependencies": { - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - } - } - }, - "@types/accepts": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz", - "integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/babel__core": { - "version": "7.1.12", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.12.tgz", - "integrity": "sha512-wMTHiiTiBAAPebqaPiPDLFA4LYPKr6Ph0Xq/6rq1Ur3v66HXyG+clfR9CNETkD7MQS8ZHvpQOtA53DLws5WAEQ==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", - "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz", - "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.11.0.tgz", - "integrity": "sha512-kSjgDMZONiIfSH1Nxcr5JIRMwUetDki63FSQfpTCz8ogF3Ulqm8+mr5f78dUYs6vMiB6gBusQqfQmBvHZj/lwg==", - "dev": true, - "requires": { - "@babel/types": "^7.3.0" - } - }, - "@types/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", - "dev": true, - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/bson": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.3.tgz", - "integrity": "sha512-mVRvYnTOZJz3ccpxhr3wgxVmSeiYinW+zlzQz3SXWaJmD1DuL05Jeq7nKw3SnbKmbleW5qrLG5vdyWe/A9sXhw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/connect": { - "version": "3.4.34", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", - "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-P1bffQfhD3O4LW0ioENXUhZ9OIa0Zn+P7M+pWgkCKaT53wVLSq0mrKksCID/FGHpFhRSxRGhgrQmfhRuzwtKdg==", - "dev": true - }, - "@types/cookies": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.6.tgz", - "integrity": "sha512-FK4U5Qyn7/Sc5ih233OuHO0qAkOpEcD/eG6584yEiLKizTFRny86qHLe/rej3HFQrkBuUjF4whFliAdODbVN/w==", - "dev": true, - "requires": { - "@types/connect": "*", - "@types/express": "*", - "@types/keygrip": "*", - "@types/node": "*" - } - }, - "@types/cors": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.8.tgz", - "integrity": "sha512-fO3gf3DxU2Trcbr75O7obVndW/X5k8rJNZkLXlQWStTHhP71PkRqjwPIEI0yMnJdg9R9OasjU+Bsr+Hr1xy/0w==", - "dev": true, - "requires": { - "@types/express": "*" - } - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/expect": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz", - "integrity": "sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==", - "dev": true - }, - "@types/express": { - "version": "4.17.7", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.7.tgz", - "integrity": "sha512-dCOT5lcmV/uC2J9k0rPafATeeyz+99xTt54ReX11/LObZgfzJqZNcW27zGhYyX+9iSEGXGt5qLPwRSvBZcLvtQ==", - "dev": true, - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "*", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.17.18", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.18.tgz", - "integrity": "sha512-m4JTwx5RUBNZvky/JJ8swEJPKFd8si08pPF2PfizYjGZOKr/svUWPcoUmLow6MmPzhasphB7gSTINY67xn3JNA==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "@types/fs-capacitor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/fs-capacitor/-/fs-capacitor-2.0.0.tgz", - "integrity": "sha512-FKVPOCFbhCvZxpVAMhdBdTfVfXUpsh15wFHgqOKxh9N9vzWZVuWCSijZ5T4U34XYNnuj2oduh6xcs1i+LPI+BQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", - "requires": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/glob-stream": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/glob-stream/-/glob-stream-6.1.0.tgz", - "integrity": "sha512-RHv6ZQjcTncXo3thYZrsbAVwoy4vSKosSWhuhuQxLOTv74OJuFQxXkmUuZCr3q9uNBEVCvIzmZL/FeRNbHZGUg==", - "dev": true, - "requires": { - "@types/glob": "*", - "@types/node": "*" - } - }, - "@types/graceful-fs": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.4.tgz", - "integrity": "sha512-mWA/4zFQhfvOA8zWkXobwJvBD7vzcxgrOQ0J5CH1votGqdq9m7+FwtGaqyCZqC3NyyBkc9z4m+iry4LlqcMWJg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/gulp": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@types/gulp/-/gulp-4.0.8.tgz", - "integrity": "sha512-RIhiptRwikdFMICikX+Kn8duKR4R7yO2CKMhkcIfvUwZ3UJSjHlvhHDJ2DsurJWETePqdjteO9MLRtObuCt7Sw==", - "dev": true, - "requires": { - "@types/undertaker": "*", - "@types/vinyl-fs": "*", - "chokidar": "^3.3.1" - } - }, - "@types/gulp-replace": { - "version": "0.0.31", - "resolved": "https://registry.npmjs.org/@types/gulp-replace/-/gulp-replace-0.0.31.tgz", - "integrity": "sha512-dbgQ1u0N9ShXrzahBgQfMSu6qUh8nlTLt7whhQ0S0sEUHhV3scysppJ1UX0fl53PJENgAL99ueykddyrCaDt7g==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/http-assert": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.1.tgz", - "integrity": "sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ==", - "dev": true - }, - "@types/http-errors": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-1.8.0.tgz", - "integrity": "sha512-2aoSC4UUbHDj2uCsCxcG/vRMXey/m17bC7UwitVm5hn22nI8O8Y9iDpA76Orc+DWkQ4zZrOKEshCqR/jSuXAHA==", - "dev": true - }, - "@types/ioredis": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@types/ioredis/-/ioredis-4.22.0.tgz", - "integrity": "sha512-BhgyAqt+CIFj/ejdYpWSGYUQzoQr7sFOBYLL8yEExa1tSTi2cy2D3a952zF8Tm4Q1cY3srn8xXZfb2riX6hWjw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@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/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/jest": { - "version": "26.0.20", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.20.tgz", - "integrity": "sha512-9zi2Y+5USJRxd0FsahERhBwlcvFh6D2GLQnY2FH2BzK8J9s9omvNHIbvABwIluXa0fD8XVKMLTO0aOEuUfACAA==", - "dev": true, - "requires": { - "jest-diff": "^26.0.0", - "pretty-format": "^26.0.0" - } - }, - "@types/keygrip": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.2.tgz", - "integrity": "sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==", - "dev": true - }, - "@types/koa": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.13.0.tgz", - "integrity": "sha512-hNs1Z2lX+R5sZroIy/WIGbPlH/719s/Nd5uIjSIAdHn9q+g7z6mxOnhwMjK1urE4/NUP0SOoYUOD4MnvD9FRNw==", - "dev": true, - "requires": { - "@types/accepts": "*", - "@types/content-disposition": "*", - "@types/cookies": "*", - "@types/http-assert": "*", - "@types/http-errors": "*", - "@types/keygrip": "*", - "@types/koa-compose": "*", - "@types/node": "*" - } - }, - "@types/koa-compose": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.5.tgz", - "integrity": "sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==", - "dev": true, - "requires": { - "@types/koa": "*" - } - }, - "@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==", - "dev": true - }, - "@types/merge2": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@types/merge2/-/merge2-1.3.0.tgz", - "integrity": "sha512-3xFWjsGhm5GCVlRrcrrVr9oapPxpbG5M3G/4JGF+Gra++7DWoeDOQphCEhyMpbpbptD3w/4PesYIMby/yHrzkQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" - }, - "@types/mongodb": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.3.tgz", - "integrity": "sha512-6YNqGP1hk5bjUFaim+QoFFuI61WjHiHE1BNeB41TA00Xd2K7zG4lcWyLLq/XtIp36uMavvS5hoAUJ+1u/GcX2Q==", - "dev": true, - "requires": { - "@types/bson": "*", - "@types/node": "*" - } - }, - "@types/mongoose": { - "version": "5.10.3", - "resolved": "https://registry.npmjs.org/@types/mongoose/-/mongoose-5.10.3.tgz", - "integrity": "sha512-VfdnaFImXEJZZiuL2ID/ysZs4inOIjxwrAnUgkr5eum2O2BLhFkiSI0i87AwignVva1qWTJ3H3DyM0Rf4USJ4A==", - "dev": true, - "requires": { - "@types/mongodb": "*", - "@types/node": "*" - } - }, - "@types/node": { - "version": "14.14.31", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.31.tgz", - "integrity": "sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==" - }, - "@types/node-fetch": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.4.tgz", - "integrity": "sha512-Oz6id++2qAOFuOlE1j0ouk1dzl3mmI1+qINPNBhi9nt/gVOz0G+13Ao6qjhdF0Ys+eOkhu6JnFmt38bR3H0POQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", - "dev": true - }, - "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true - }, - "@types/prettier": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.1.6.tgz", - "integrity": "sha512-6gOkRe7OIioWAXfnO/2lFiv+SJichKVSys1mSsgyrYHSEjk8Ctv4tSR/Odvnu+HWlH2C8j53dahU03XmQdd5fA==", - "dev": true - }, - "@types/qs": { - "version": "6.9.5", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.5.tgz", - "integrity": "sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ==", - "dev": true - }, - "@types/range-parser": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", - "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", - "dev": true - }, - "@types/rimraf": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-3.0.0.tgz", - "integrity": "sha512-7WhJ0MdpFgYQPXlF4Dx+DhgvlPCfz/x5mHaeDQAKhcenvQP1KCpLQ18JklAqeGMYSAT2PxLpzd0g2/HE7fj7hQ==", - "dev": true, - "requires": { - "@types/glob": "*", - "@types/node": "*" - } - }, - "@types/semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-+nVsLKlcUCeMzD2ufHEYuJ9a2ovstb6Dp52A5VsoKxDXgvE051XgHI/33I1EymwkRGQkwnA0LkhnUzituGs4EQ==" - }, - "@types/serve-static": { - "version": "1.13.9", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz", - "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==", - "dev": true, - "requires": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", - "dev": true - }, - "@types/undertaker": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@types/undertaker/-/undertaker-1.2.6.tgz", - "integrity": "sha512-sG5MRcsWRokQXtj94uCqPxReXldm4ZvXif34YthgHEpzipcBAFTg+4IoWFcvdA0hGM1KdpPj2efdzcD2pETqQA==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/undertaker-registry": "*", - "async-done": "~1.3.2" - } - }, - "@types/undertaker-registry": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/undertaker-registry/-/undertaker-registry-1.0.1.tgz", - "integrity": "sha512-Z4TYuEKn9+RbNVk1Ll2SS4x1JeLHecolIbM/a8gveaHsW0Hr+RQMraZACwTO2VD7JvepgA6UO1A1VrbktQrIbQ==", - "dev": true - }, - "@types/validator": { - "version": "13.1.3", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.1.3.tgz", - "integrity": "sha512-DaOWN1zf7j+8nHhqXhIgNmS+ltAC53NXqGxYuBhWqWgqolRhddKzfZU814lkHQSTG0IUfQxU7Cg0gb8fFWo2mA==", - "dev": true - }, - "@types/vinyl": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.4.tgz", - "integrity": "sha512-2o6a2ixaVI2EbwBPg1QYLGQoHK56p/8X/sGfKbFC8N6sY9lfjsMf/GprtkQkSya0D4uRiutRZ2BWj7k3JvLsAQ==", - "dev": true, - "requires": { - "@types/expect": "^1.20.4", - "@types/node": "*" - } - }, - "@types/vinyl-fs": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/@types/vinyl-fs/-/vinyl-fs-2.4.11.tgz", - "integrity": "sha512-2OzQSfIr9CqqWMGqmcERE6Hnd2KY3eBVtFaulVo3sJghplUcaeMdL9ZjEiljcQQeHjheWY9RlNmumjIAvsBNaA==", - "dev": true, - "requires": { - "@types/glob-stream": "*", - "@types/node": "*", - "@types/vinyl": "*" - } - }, - "@types/ws": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.0.tgz", - "integrity": "sha512-Y29uQ3Uy+58bZrFLhX36hcI3Np37nqWE7ky5tjiDoy1GDZnIwVxS0CgF+s+1bXMzjKBFy+fqaRfb708iNzdinw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/yargs": { - "version": "15.0.12", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.12.tgz", - "integrity": "sha512-f+fD/fQAo3BCbCDlrUpznF1A5Zp9rB0noS5vnoormHSIPFKL0Z2DcUJ3Gxp5ytH4uLRNxy7AwYUC9exZzqGMAw==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", - "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==", - "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==", - "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 - } - } - }, - "abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", - "dev": true - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dev": true, - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "requires": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true - }, - "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, - "requires": { - "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "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 - } - } - }, - "agentkeepalive": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.1.3.tgz", - "integrity": "sha512-wn8fw19xKZwdGPO47jivonaHRTd+nGOMP1z11sgGeQzDy2xd5FG0R67dIMcKHDE2cJ5y+YXV30XVGUBPRSY7Hg==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "depd": "^1.1.2", - "humanize-ms": "^1.2.1" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "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": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.0.tgz", - "integrity": "sha512-yKD9kEoJIR+2IFqhMwayIBgheLYbB3PS2OBhWae1L/ODTd/JF/30cW0bc9TqzRL3k4U41Dieu3BF4I29p8xesA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^3.2.0" - }, - "dependencies": { - "indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", - "dev": true - } - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "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" - } - }, - "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==", - "dev": true - }, - "ansi-escapes": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", - "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", - "dev": true, - "requires": { - "type-fest": "^0.11.0" - } - }, - "ansi-gray": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", - "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "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" - } - }, - "ansi-wrap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", - "dev": true - }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", - "dev": true - }, - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "apollo-cache-control": { - "version": "0.11.6", - "resolved": "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.11.6.tgz", - "integrity": "sha512-YZ+uuIG+fPy+mkpBS2qKF0v1qlzZ3PW6xZVaDukeK3ed3iAs4L/2YnkTqau3OmoF/VPzX2FmSkocX/OVd59YSw==", - "dev": true, - "requires": { - "apollo-server-env": "^3.0.0", - "apollo-server-plugin-base": "^0.10.4" - } - }, - "apollo-datasource": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-0.7.3.tgz", - "integrity": "sha512-PE0ucdZYjHjUyXrFWRwT02yLcx2DACsZ0jm1Mp/0m/I9nZu/fEkvJxfsryXB6JndpmQO77gQHixf/xGCN976kA==", - "dev": true, - "requires": { - "apollo-server-caching": "^0.5.3", - "apollo-server-env": "^3.0.0" - } - }, - "apollo-env": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/apollo-env/-/apollo-env-0.6.6.tgz", - "integrity": "sha512-hXI9PjJtzmD34XviBU+4sPMOxnifYrHVmxpjykqI/dUD2G3yTiuRaiQqwRwB2RCdwC1Ug/jBfoQ/NHDTnnjndQ==", - "dev": true, - "requires": { - "@types/node-fetch": "2.5.7", - "core-js": "^3.0.1", - "node-fetch": "^2.2.0", - "sha.js": "^2.4.11" - }, - "dependencies": { - "@types/node-fetch": { - "version": "2.5.7", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.7.tgz", - "integrity": "sha512-o2WVNf5UhWRkxlf6eq+jMZDu7kjgpgJfl4xVNlvryc95O/6F2ld8ztKX+qu+Rjyet93WAWm5LjeX9H5FGkODvw==", - "dev": true, - "requires": { - "@types/node": "*", - "form-data": "^3.0.0" - } - } - } - }, - "apollo-graphql": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/apollo-graphql/-/apollo-graphql-0.6.0.tgz", - "integrity": "sha512-BxTf5LOQe649e9BNTPdyCGItVv4Ll8wZ2BKnmiYpRAocYEXAVrQPWuSr3dO4iipqAU8X0gvle/Xu9mSqg5b7Qg==", - "dev": true, - "requires": { - "apollo-env": "^0.6.5", - "lodash.sortby": "^4.7.0" - } - }, - "apollo-link": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.14.tgz", - "integrity": "sha512-p67CMEFP7kOG1JZ0ZkYZwRDa369w5PIjtMjvrQd/HnIV8FRsHRqLqK+oAZQnFa1DDdZtOtHTi+aMIW6EatC2jg==", - "dev": true, - "requires": { - "apollo-utilities": "^1.3.0", - "ts-invariant": "^0.4.0", - "tslib": "^1.9.3", - "zen-observable-ts": "^0.8.21" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } - } - }, - "apollo-reporting-protobuf": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-0.6.2.tgz", - "integrity": "sha512-WJTJxLM+MRHNUxt1RTl4zD0HrLdH44F2mDzMweBj1yHL0kSt8I1WwoiF/wiGVSpnG48LZrBegCaOJeuVbJTbtw==", - "dev": true, - "requires": { - "@apollo/protobufjs": "^1.0.3" - } - }, - "apollo-server": { - "version": "2.21.0", - "resolved": "https://registry.npmjs.org/apollo-server/-/apollo-server-2.21.0.tgz", - "integrity": "sha512-OqngjOSB0MEH6VKGWHcrqt4y39HlhYh9CrMvn4PhadTt53IPYRmBglk5qSRA8xMorGqy60iKrOReqj5YfCjTOg==", - "dev": true, - "requires": { - "apollo-server-core": "^2.21.0", - "apollo-server-express": "^2.21.0", - "express": "^4.0.0", - "graphql-subscriptions": "^1.0.0", - "graphql-tools": "^4.0.8", - "stoppable": "^1.1.0" - } - }, - "apollo-server-caching": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.5.3.tgz", - "integrity": "sha512-iMi3087iphDAI0U2iSBE9qtx9kQoMMEWr6w+LwXruBD95ek9DWyj7OeC2U/ngLjRsXM43DoBDXlu7R+uMjahrQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "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" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "apollo-server-core": { - "version": "2.21.0", - "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.21.0.tgz", - "integrity": "sha512-GtIiq2F0dVDLzzIuO5+dK/pGq/sGxYlKCqAuQQqzYg0fvZ7fukyluXtcTe0tMI+FJZjU0j0WnKgiLsboCoAlPQ==", - "dev": true, - "requires": { - "@apollographql/apollo-tools": "^0.4.3", - "@apollographql/graphql-playground-html": "1.6.26", - "@apollographql/graphql-upload-8-fork": "^8.1.3", - "@types/ws": "^7.0.0", - "apollo-cache-control": "^0.11.6", - "apollo-datasource": "^0.7.3", - "apollo-graphql": "^0.6.0", - "apollo-reporting-protobuf": "^0.6.2", - "apollo-server-caching": "^0.5.3", - "apollo-server-env": "^3.0.0", - "apollo-server-errors": "^2.4.2", - "apollo-server-plugin-base": "^0.10.4", - "apollo-server-types": "^0.6.3", - "apollo-tracing": "^0.12.2", - "async-retry": "^1.2.1", - "fast-json-stable-stringify": "^2.0.0", - "graphql-extensions": "^0.12.8", - "graphql-tag": "^2.11.0", - "graphql-tools": "^4.0.8", - "loglevel": "^1.6.7", - "lru-cache": "^6.0.0", - "sha.js": "^2.4.11", - "subscriptions-transport-ws": "^0.9.11", - "uuid": "^8.0.0", - "ws": "^6.0.0" - }, - "dependencies": { - "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" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "apollo-server-env": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-3.0.0.tgz", - "integrity": "sha512-tPSN+VttnPsoQAl/SBVUpGbLA97MXG990XIwq6YUnJyAixrrsjW1xYG7RlaOqetxm80y5mBZKLrRDiiSsW/vog==", - "dev": true, - "requires": { - "node-fetch": "^2.1.2", - "util.promisify": "^1.0.0" - } - }, - "apollo-server-errors": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-2.4.2.tgz", - "integrity": "sha512-FeGxW3Batn6sUtX3OVVUm7o56EgjxDlmgpTLNyWcLb0j6P8mw9oLNyAm3B+deHA4KNdNHO5BmHS2g1SJYjqPCQ==", - "dev": true, - "requires": {} - }, - "apollo-server-express": { - "version": "2.21.0", - "resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-2.21.0.tgz", - "integrity": "sha512-zbOSNGuxUjlOFZnRrbMpga3pKDEroitF4NAqoVxgBivx7v2hGsE7rljct3PucTx2cMN90AyYe3cU4oA8jBxZIQ==", - "dev": true, - "requires": { - "@apollographql/graphql-playground-html": "1.6.26", - "@types/accepts": "^1.3.5", - "@types/body-parser": "1.19.0", - "@types/cors": "2.8.8", - "@types/express": "4.17.7", - "@types/express-serve-static-core": "4.17.18", - "accepts": "^1.3.5", - "apollo-server-core": "^2.21.0", - "apollo-server-types": "^0.6.3", - "body-parser": "^1.18.3", - "cors": "^2.8.4", - "express": "^4.17.1", - "graphql-subscriptions": "^1.0.0", - "graphql-tools": "^4.0.8", - "parseurl": "^1.3.2", - "subscriptions-transport-ws": "^0.9.16", - "type-is": "^1.6.16" - } - }, - "apollo-server-plugin-base": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.10.4.tgz", - "integrity": "sha512-HRhbyHgHFTLP0ImubQObYhSgpmVH4Rk1BinnceZmwudIVLKrqayIVOELdyext/QnSmmzg5W7vF3NLGBcVGMqDg==", - "dev": true, - "requires": { - "apollo-server-types": "^0.6.3" - } - }, - "apollo-server-plugin-response-cache": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/apollo-server-plugin-response-cache/-/apollo-server-plugin-response-cache-0.6.0.tgz", - "integrity": "sha512-Yjwec1VXINmNV6tmZLv+J9+iPb/4oKPcVA2YwF05o3Lf/oO+T5/9DP1yHxxjB117KDYlepKeIPuzAcqFZW/l8g==", - "dev": true, - "requires": { - "apollo-cache-control": "^0.11.6", - "apollo-server-caching": "^0.5.3", - "apollo-server-plugin-base": "^0.10.4" - } - }, - "apollo-server-types": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-0.6.3.tgz", - "integrity": "sha512-aVR7SlSGGY41E1f11YYz5bvwA89uGmkVUtzMiklDhZ7IgRJhysT5Dflt5IuwDxp+NdQkIhVCErUXakopocFLAg==", - "dev": true, - "requires": { - "apollo-reporting-protobuf": "^0.6.2", - "apollo-server-caching": "^0.5.3", - "apollo-server-env": "^3.0.0" - } - }, - "apollo-tracing": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.12.2.tgz", - "integrity": "sha512-SYN4o0C0wR1fyS3+P0FthyvsQVHFopdmN3IU64IaspR/RZScPxZ3Ae8uu++fTvkQflAkglnFM0aX6DkZERBp6w==", - "dev": true, - "requires": { - "apollo-server-env": "^3.0.0", - "apollo-server-plugin-base": "^0.10.4" - } - }, - "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-root-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.0.0.tgz", - "integrity": "sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==", - "dev": true - }, - "append-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", - "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", - "dev": true, - "requires": { - "buffer-equal": "^1.0.0" - } - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "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 - }, - "arr-filter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", - "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=", - "dev": true, - "requires": { - "make-iterator": "^1.0.0" - } - }, - "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 - }, - "arr-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", - "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=", - "dev": true, - "requires": { - "make-iterator": "^1.0.0" - } - }, - "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 - }, - "array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", - "dev": true - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true - }, - "array-initial": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", - "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=", - "dev": true, - "requires": { - "array-slice": "^1.0.0", - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } - } - }, - "array-last": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", - "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", - "dev": true, - "requires": { - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } - } - }, - "array-slice": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", - "dev": true - }, - "array-sort": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", - "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", - "dev": true, - "requires": { - "default-compare": "^1.0.0", - "get-value": "^2.0.6", - "kind-of": "^5.0.2" - } - }, - "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 - }, - "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 - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "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 - }, - "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 - }, - "async-done": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz", - "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.2", - "process-nextick-args": "^2.0.0", - "stream-exhaust": "^1.0.1" - } - }, - "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 - }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, - "async-retry": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.1.tgz", - "integrity": "sha512-aiieFW/7h3hY0Bq5d+ktDBejxuwR78vRu9hDUdR8rNhSaQ29VzPL4AoIRG7D/c7tdenwOcKvgPM6tIxB3cB6HA==", - "dev": true, - "requires": { - "retry": "0.12.0" - } - }, - "async-settle": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", - "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=", - "dev": true, - "requires": { - "async-done": "^1.2.2" - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "asyncro": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/asyncro/-/asyncro-3.0.0.tgz", - "integrity": "sha512-nEnWYfrBmA3taTiuiOoZYmgJ/CNrSoQLeLs29SeLcPu60yaw/mHDBHV0iOZ051fTvsTHxpCY+gXibqT9wbQYfg==", - "dev": true - }, - "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 - }, - "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 - }, - "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=", - "dev": true - }, - "aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true - }, - "babel-jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", - "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", - "dev": true, - "requires": { - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/babel__core": "^7.1.7", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "slash": "^3.0.0" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "babel-plugin-istanbul": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", - "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^4.0.0", - "test-exclude": "^6.0.0" - } - }, - "babel-plugin-jest-hoist": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", - "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "requires": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - } - }, - "babel-preset-jest": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", - "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^26.6.2", - "babel-preset-current-node-syntax": "^1.0.0" - } - }, - "bach": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", - "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=", - "dev": true, - "requires": { - "arr-filter": "^1.1.1", - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "array-each": "^1.0.0", - "array-initial": "^1.0.0", - "array-last": "^1.1.1", - "async-done": "^1.2.2", - "async-settle": "^1.0.0", - "now-and-later": "^2.0.0" - } - }, - "backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": 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, - "requires": { - "is-descriptor": "^1.0.0" - } - } - } - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": 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=", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "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 - }, - "binaryextensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-2.3.0.tgz", - "integrity": "sha512-nAihlQsYGyc5Bwq6+EsubvANYGExeJKHDO3RjnvwU042fawQTQfM3Kxn7IHUXQOz4bzfwsGYYHGSvXyW4zOGLg==", - "dev": 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==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "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==", - "dev": true, - "requires": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" - } - }, - "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", - "dev": true - }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "dev": true, - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "dependencies": { - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.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" - } - }, - "browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "requires": { - "fast-json-stable-stringify": "2.x" - } - }, - "bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "requires": { - "node-int64": "^0.4.0" - } - }, - "bson": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.5.tgz", - "integrity": "sha512-kDuEzldR21lHciPQAIulLs1LZlCXdLziXI6Mb/TDkwXhb//UORJNPXgcRs2CuO4H0DcMkpfT3/ySsP3unoZjBg==", - "dev": true - }, - "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" - } - }, - "buffer-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", - "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", - "dev": true - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "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==", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "busboy": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.3.1.tgz", - "integrity": "sha512-y7tTxhGKXcyBxRKAni+awqx8uqaJKrSFSNFSeRG5CsWNdmy2BIK+6VGWEW7TZnIO/533mtMEA4rOevQV815YJw==", - "dev": true, - "requires": { - "dicer": "0.3.0" - } - }, - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true - }, - "cacache": { - "version": "15.0.5", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.5.tgz", - "integrity": "sha512-lloiL22n7sOjEEXdL8NAjTgv9a1u43xICE9/203qonkZUCj5X1UEWIdf2/Y0d6QcCtMzbKQyhrcDbdvlZTs/+A==", - "dev": true, - "requires": { - "@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.0", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" - }, - "dependencies": { - "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" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "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, - "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" - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "capture-exit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", - "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", - "dev": true, - "requires": { - "rsvp": "^4.8.4" - } - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "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" - } - }, - "char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true - }, - "chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - } - }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "cjs-module-lexer": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", - "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", - "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==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "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, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "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, - "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, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "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=", - "dev": 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, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - } - } - }, - "class-validator": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.13.1.tgz", - "integrity": "sha512-zWIeYFhUitvAHBwNhDdCRK09hWx+P0HUwFE8US8/CxFpMVzkUK8RJl7yOIE+BVu2lxyPNgeOaFv78tLE47jBIg==", - "dev": true, - "requires": { - "@types/validator": "^13.1.3", - "libphonenumber-js": "^1.9.7", - "validator": "^13.5.2" - } - }, - "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 - }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "cli-highlight": { - "version": "2.1.10", - "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.10.tgz", - "integrity": "sha512-CcPFD3JwdQ2oSzy+AMG6j3LRTkNjM82kzcSKzoVw6cLanDCJNlsLjeqVTOTfOfucnWv5F0rmBemVf1m9JiIasw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "highlight.js": "^10.0.0", - "mz": "^2.4.0", - "parse5": "^5.1.1", - "parse5-htmlparser2-tree-adapter": "^6.0.0", - "yargs": "^16.0.0" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "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 - }, - "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": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", - "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", - "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } - } - }, - "cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", - "dev": true, - "requires": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - } - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "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=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - } - } - }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", - "dev": true - }, - "clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", - "dev": true - }, - "clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", - "dev": true - }, - "cloneable-readable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", - "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "process-nextick-args": "^2.0.0", - "readable-stream": "^2.3.5" - } - }, - "cluster-key-slot": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz", - "integrity": "sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==", - "dev": true - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "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=", - "dev": true - }, - "collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true - }, - "collection-map": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", - "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=", - "dev": true, - "requires": { - "arr-map": "^2.0.2", - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.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==", - "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 - }, - "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==", - "dev": true - }, - "colorette": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", - "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", - "dev": true - }, - "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 - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "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, - "requires": { - "safe-buffer": "5.1.2" - } - }, - "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==", - "dev": true - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", - "dev": true - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "copy-props": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.4.tgz", - "integrity": "sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==", - "dev": true, - "requires": { - "each-props": "^1.3.0", - "is-plain-object": "^2.0.1" - } - }, - "core-js": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.2.tgz", - "integrity": "sha512-FfApuSRgrR6G5s58casCBd9M2k+4ikuu4wbW6pJyYU7bd9zvFc9qf7vr5xmrZOhT9nn+8uwlH1oRR9jTnFoA3A==", - "dev": true - }, - "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=", - "dev": true - }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dev": true, - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "cosmiconfig": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", - "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", - "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" - } - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "cross-fetch": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.0.6.tgz", - "integrity": "sha512-KBPUbqgFjzWlVcURG+Svp9TlhA5uliYtiNx/0r8nv0pdypeQCRJ9IaSIc3q/x3q8t3F75cHuwxVql1HFGHCNJQ==", - "dev": true, - "requires": { - "node-fetch": "2.6.1" - } - }, - "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" - } - }, - "cssfilter": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz", - "integrity": "sha1-xtJnJjKi5cg+AT5oZKQs6N79IK4=", - "dev": true - }, - "cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true - }, - "cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "requires": { - "cssom": "~0.3.6" - }, - "dependencies": { - "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - } - } - }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "requires": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - } - }, - "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" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decimal.js": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", - "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==", - "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 - }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", - "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 - }, - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true - }, - "default-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", - "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", - "dev": true, - "requires": { - "kind-of": "^5.0.2" - } - }, - "default-resolution": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", - "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=", - "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, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "del": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/del/-/del-6.0.0.tgz", - "integrity": "sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ==", - "dev": true, - "requires": { - "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" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "denque": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz", - "integrity": "sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ==", - "dev": true - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "deprecated-decorator": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz", - "integrity": "sha1-AJZjF7ehL+kvPMgx91g68ym4bDc=", - "dev": true - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", - "dev": true - }, - "detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true - }, - "dicer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz", - "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==", - "dev": true, - "requires": { - "streamsearch": "0.1.2" - } - }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, - "diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", - "dev": true - }, - "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, - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-0.7.2.tgz", - "integrity": "sha1-fLhgNZujvpDgQLJrcpzkv6ZUxSM=", - "dev": true, - "requires": { - "esutils": "^1.1.6", - "isarray": "0.0.1" - }, - "dependencies": { - "esutils": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz", - "integrity": "sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U=", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - } - } - }, - "domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dev": true, - "requires": { - "webidl-conversions": "^5.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true - } - } - }, - "dotenv": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", - "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==", - "dev": true - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "each-props": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", - "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.1", - "object.defaults": "^1.1.0" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "editions": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz", - "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==", - "dev": true - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "emittery": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", - "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true - }, - "encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "dev": true, - "optional": true, - "requires": { - "iconv-lite": "^0.6.2" - }, - "dependencies": { - "iconv-lite": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", - "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - } - } - }, - "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==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "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, - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "err-code": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", - "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.18.0-next.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.2.tgz", - "integrity": "sha512-Ih4ZMFHEtZupnUh6497zEL4y2+w8+1ljnCyaTa+adcoafI1GOvMwFlDjBLfWR7y9VLfrjRJe9ocuHY1PSR9jjw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.1", - "object-inspect": "^1.9.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.3", - "string.prototype.trimstart": "^1.0.3" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es5-ext": { - "version": "0.10.53", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", - "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", - "dev": true, - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "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==", - "dev": true, - "requires": { - "d": "^1.0.1", - "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==", - "dev": true, - "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 - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "escaya": { - "version": "0.0.61", - "resolved": "https://registry.npmjs.org/escaya/-/escaya-0.0.61.tgz", - "integrity": "sha512-WLLmvdG72Z0pCq8XUBd03GEJlAiMceXFanjdQeEzeSiuV1ZgrJqbkU7ZEe/hu0OsBlg5wLlySEeOvfzcGoO8mg==", - "dev": true - }, - "escodegen": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", - "dev": true, - "requires": { - "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "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 - } - } - }, - "esm": { - "version": "3.2.25", - "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", - "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", - "dev": true - }, - "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 - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true - }, - "eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "exec-sh": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", - "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", - "dev": true - }, - "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" - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true - }, - "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, - "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": { - "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, - "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, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "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, - "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, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "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=", - "dev": 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, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "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 - } - } - }, - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "expect": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" - } - }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "dev": true, - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - } - }, - "ext": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", - "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", - "dev": true, - "requires": { - "type": "^2.0.0" - }, - "dependencies": { - "type": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.3.0.tgz", - "integrity": "sha512-rgPIqOdfK/4J9FhiVrZ3cveAjRRo5rsQBAIhnylX874y1DX/kEKSVdLsnuHB6l1KTjHyU01VjiMBHgU2adejyg==", - "dev": true - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": 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, - "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, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "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 - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "fancy-log": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", - "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", - "dev": true, - "requires": { - "ansi-gray": "^0.1.1", - "color-support": "^1.1.3", - "parse-node-version": "^1.0.0", - "time-stamp": "^1.0.0" - } - }, - "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==", - "dev": true - }, - "fast-glob": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", - "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", - "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" - } - }, - "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==", - "dev": true - }, - "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 - }, - "fastq": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.10.0.tgz", - "integrity": "sha512-NL2Qc5L3iQEsyYzweq7qfgy5OtXCmGzGvhElGEd/SoFWEMOEczNh5s5ocaF01HDetxz+p8ecjNPA6cZxxIHmzA==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", - "dev": true, - "requires": { - "bser": "2.1.1" - } - }, - "figlet": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.5.0.tgz", - "integrity": "sha512-ZQJM4aifMpz6H19AW1VqvZ7l4pOE9p7i/3LyxgO2kp+PO/VcDYNqIHEMtkccqIhTXMKci4kjueJr/iCQEaT/Ww==", - "dev": true - }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "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 - }, - "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" - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - } - }, - "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" - } - }, - "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, - "requires": { - "semver-regex": "^3.1.2" - } - }, - "findup-sync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", - "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - }, - "dependencies": { - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": 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, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": 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, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "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 - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": 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, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "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 - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": 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" - } - }, - "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=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } - } - }, - "fined": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", - "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "is-plain-object": "^2.0.3", - "object.defaults": "^1.1.0", - "object.pick": "^1.2.0", - "parse-filepath": "^1.0.1" - } - }, - "flagged-respawn": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", - "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", - "dev": true - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "requires": { - "is-callable": "^1.1.3" - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", - "dev": true - }, - "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, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true - }, - "fs-capacitor": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/fs-capacitor/-/fs-capacitor-2.0.4.tgz", - "integrity": "sha512-8S4f4WsCryNw2mJJchi46YgB6CR5Ze+4L1h8ewl9tEpL4SJ3ZO+c/bS4BWhB8bK+O3TMqhuZarTitd0S0eh2pA==", - "dev": true - }, - "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" - } - }, - "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" - } - }, - "fs-mkdirp-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", - "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "through2": "^2.0.3" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "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==", - "dev": true - }, - "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 - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-intrinsic": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.2.tgz", - "integrity": "sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "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 - }, - "get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true - }, - "get-stream": { - "version": "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 - }, - "getopts": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.2.5.tgz", - "integrity": "sha512-9jb7AW5p3in+IiJWhQiZmmwkpLaR/ccTWdWQCtZM66HJcHHLegowh4q4tSD7gouUyeNvFWRavfK9GXosQHDpFA==", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "requires": { - "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" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "glob-stream": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", - "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", - "dev": true, - "requires": { - "extend": "^3.0.0", - "glob": "^7.1.1", - "glob-parent": "^3.1.0", - "is-negated-glob": "^1.0.0", - "ordered-read-streams": "^1.0.0", - "pumpify": "^1.3.5", - "readable-stream": "^2.1.5", - "remove-trailing-separator": "^1.0.1", - "to-absolute-glob": "^2.0.0", - "unique-stream": "^2.0.2" - }, - "dependencies": { - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "glob-watcher": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.5.tgz", - "integrity": "sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-done": "^1.2.0", - "chokidar": "^2.0.0", - "is-negated-glob": "^1.0.0", - "just-debounce": "^1.0.0", - "normalize-path": "^3.0.0", - "object.defaults": "^1.1.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": 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, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": 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, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": 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" - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": 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, - "requires": { - "is-extendable": "^0.1.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, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": 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, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "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=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "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 - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": 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" - }, - "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 - } - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "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=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } - } - }, - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "requires": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - } - }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - }, - "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" - } - } - } - }, - "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 - }, - "globby": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.2.tgz", - "integrity": "sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og==", - "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", - "slash": "^3.0.0" - } - }, - "glogg": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", - "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", - "dev": true, - "requires": { - "sparkles": "^1.0.0" - } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "graphql": { - "version": "15.5.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.5.0.tgz", - "integrity": "sha512-OmaM7y0kaK31NKG31q4YbD2beNYa6jBBKtMFT6gLYJljHLJr42IqJ8KX08u3Li/0ifzTU5HjmoOOrwa5BRLeDA==" - }, - "graphql-extensions": { - "version": "0.12.8", - "resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.12.8.tgz", - "integrity": "sha512-xjsSaB6yKt9jarFNNdivl2VOx52WySYhxPgf8Y16g6GKZyAzBoIFiwyGw5PJDlOSUa6cpmzn6o7z8fVMbSAbkg==", - "dev": true, - "requires": { - "@apollographql/apollo-tools": "^0.4.3", - "apollo-server-env": "^3.0.0", - "apollo-server-types": "^0.6.3" - } - }, - "graphql-query-complexity": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/graphql-query-complexity/-/graphql-query-complexity-0.7.2.tgz", - "integrity": "sha512-+VgmrfxGEjHI3zuojWOR8bsz7Ycz/BZjNjxnlUieTz5DsB92WoIrYCSZdWG7UWZ3rfcA1Gb2Nf+wB80GsaZWuQ==", - "requires": { - "lodash.get": "^4.4.2" - } - }, - "graphql-redis-subscriptions": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/graphql-redis-subscriptions/-/graphql-redis-subscriptions-2.3.1.tgz", - "integrity": "sha512-ztS3ZXBSoPJ8Q0/o7PG2iLO6QWq2tlJrukiBJCjgMccRv1I3lt3HmLjiH2CbDjPhpoINttZNoytQbxE0OE/UpA==", - "dev": true, - "requires": { - "ioredis": "^4.17.3", - "iterall": "^1.3.0" - } - }, - "graphql-subscriptions": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-1.2.0.tgz", - "integrity": "sha512-uXvp729fztqwa7HFUFaAqKwNMwwOfsvu4HwOu7/35Cd44bNrMPCn97mNGN0ybuuZE36CPXBTaW/4U/xyOS4D9w==", - "requires": { - "iterall": "^1.3.0" - } - }, - "graphql-tag": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.11.0.tgz", - "integrity": "sha512-VmsD5pJqWJnQZMUeRwrDhfgoyqcfwEkvtpANqcoUG8/tOLkwNgU9mzub/Mc78OJMhHjx7gfAMTxzdG43VGg3bA==", - "dev": true, - "requires": {} - }, - "graphql-tools": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-4.0.8.tgz", - "integrity": "sha512-MW+ioleBrwhRjalKjYaLQbr+920pHBgy9vM/n47sswtns8+96sRn5M/G+J1eu7IMeKWiN/9p6tmwCHU7552VJg==", - "dev": true, - "requires": { - "apollo-link": "^1.2.14", - "apollo-utilities": "^1.0.1", - "deprecated-decorator": "^0.1.6", - "iterall": "^1.1.3", - "uuid": "^3.1.0" - }, - "dependencies": { - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - } - } - }, - "growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", - "dev": true, - "optional": true - }, - "gulp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", - "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", - "dev": true, - "requires": { - "glob-watcher": "^5.0.3", - "gulp-cli": "^2.2.0", - "undertaker": "^1.2.1", - "vinyl-fs": "^3.0.0" - } - }, - "gulp-cli": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz", - "integrity": "sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==", - "dev": true, - "requires": { - "ansi-colors": "^1.0.1", - "archy": "^1.0.0", - "array-sort": "^1.0.0", - "color-support": "^1.1.3", - "concat-stream": "^1.6.0", - "copy-props": "^2.0.1", - "fancy-log": "^1.3.2", - "gulplog": "^1.0.0", - "interpret": "^1.4.0", - "isobject": "^3.0.1", - "liftoff": "^3.1.0", - "matchdep": "^2.0.0", - "mute-stdout": "^1.0.0", - "pretty-hrtime": "^1.0.0", - "replace-homedir": "^1.0.0", - "semver-greatest-satisfied-range": "^1.1.0", - "v8flags": "^3.2.0", - "yargs": "^7.1.0" - }, - "dependencies": { - "ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "requires": { - "ansi-wrap": "^0.1.0" - } - } - } - }, - "gulp-replace": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulp-replace/-/gulp-replace-1.0.0.tgz", - "integrity": "sha512-lgdmrFSI1SdhNMXZQbrC75MOl1UjYWlOWNbNRnz+F/KHmgxt3l6XstBoAYIdadwETFyG/6i+vWUSCawdC3pqOw==", - "dev": true, - "requires": { - "istextorbinary": "2.2.1", - "readable-stream": "^2.0.1", - "replacestream": "^4.0.0" - } - }, - "gulp-shell": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/gulp-shell/-/gulp-shell-0.8.0.tgz", - "integrity": "sha512-wHNCgmqbWkk1c6Gc2dOL5SprcoeujQdeepICwfQRo91DIylTE7a794VEE+leq3cE2YDoiS5ulvRfKVIEMazcTQ==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "fancy-log": "^1.3.3", - "lodash.template": "^4.5.0", - "plugin-error": "^1.0.1", - "through2": "^3.0.1", - "tslib": "^1.10.0" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } - } - }, - "gulp-typescript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/gulp-typescript/-/gulp-typescript-5.0.1.tgz", - "integrity": "sha512-YuMMlylyJtUSHG1/wuSVTrZp60k1dMEFKYOvDf7OvbAJWrDtxxD4oZon4ancdWwzjj30ztiidhe4VXJniF0pIQ==", - "dev": true, - "requires": { - "ansi-colors": "^3.0.5", - "plugin-error": "^1.0.1", - "source-map": "^0.7.3", - "through2": "^3.0.0", - "vinyl": "^2.1.0", - "vinyl-fs": "^3.0.3" - }, - "dependencies": { - "ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", - "dev": true - } - } - }, - "gulpclass": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/gulpclass/-/gulpclass-0.2.0.tgz", - "integrity": "sha512-S2p0SgnVLjBbIEw5tHbBV6Wm6abD+leA5xZG6ukf9M+j1I/8zIeKPby9GLWnI90671YRk+lXbvEUROKaZXo8NA==", - "dev": true, - "requires": { - "@types/gulp": "^4.0.5", - "@types/merge2": "^1.1.4", - "@types/node": "*", - "gulp": "^4.0.0", - "merge2": "^1.2.2" - } - }, - "gulplog": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", - "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", - "dev": true, - "requires": { - "glogg": "^1.0.0" - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "dev": true, - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "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 - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "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, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": 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, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "highlight.js": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.6.0.tgz", - "integrity": "sha512-8mlRcn5vk/r4+QcqerapwBYTe+iPL5ih6xrNylxrnBdHQiijDETfXX7VIxC3UiCRiINBJfANBAsPzAvRQj8RpQ==", - "dev": true - }, - "homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, - "requires": { - "parse-passwd": "^1.0.0" - } - }, - "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", - "dev": true - }, - "html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "requires": { - "whatwg-encoding": "^1.0.5" - } - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, - "http-errors": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", - "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - } - }, - "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, - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "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=", - "dev": true, - "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==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "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 - } - } - }, - "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 - }, - "humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", - "dev": true, - "requires": { - "ms": "^2.0.0" - } - }, - "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": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.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" - } - }, - "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" - } - } - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true - }, - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - }, - "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" - } - }, - "import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", - "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "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 - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "ioredis": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.23.0.tgz", - "integrity": "sha512-R5TDCODwnEH3J3A5TSoB17+6a+SeJTtIOW6vsy5Q1yag/AM8FejHjZC5R2O1QepSXV8hwOnGSm/4buJc/LeXTQ==", - "dev": true, - "requires": { - "cluster-key-slot": "^1.1.0", - "debug": "^4.1.1", - "denque": "^1.1.0", - "lodash.defaults": "^4.2.0", - "lodash.flatten": "^4.4.0", - "p-map": "^2.1.0", - "redis-commands": "1.7.0", - "redis-errors": "^1.2.0", - "redis-parser": "^3.0.0", - "standard-as-callback": "^2.0.1" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "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 - }, - "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 - } - } - }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - }, - "ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", - "dev": true - }, - "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==", - "dev": true - }, - "is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "dev": true, - "requires": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - } - }, - "is-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, - "requires": { - "kind-of": "^6.0.0" - }, - "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 - } - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "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, - "requires": { - "binary-extensions": "^2.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 - }, - "is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", - "dev": true - }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "requires": { - "ci-info": "^2.0.0" - } - }, - "is-core-module": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", - "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "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, - "requires": { - "kind-of": "^6.0.0" - }, - "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 - } - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "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, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "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 - } - } - }, - "is-docker": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", - "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==", - "dev": true, - "optional": true - }, - "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, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "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 - }, - "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-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true - }, - "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, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-invalid-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-invalid-path/-/is-invalid-path-0.1.0.tgz", - "integrity": "sha1-MHqFWzzxqTi0TqcNLGEQYFNxTzQ=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - }, - "dependencies": { - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - } - } - }, - "is-lambda": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=", - "dev": true - }, - "is-negated-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", - "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", - "dev": true - }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "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 - }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", - "dev": true - }, - "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 - }, - "is-path-inside": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", - "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", - "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, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-potential-custom-element-name": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", - "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", - "dev": true - }, - "is-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", - "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.1" - } - }, - "is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", - "dev": true - }, - "is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "dev": true, - "requires": { - "is-unc-path": "^1.0.0" - } - }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "dev": true, - "requires": { - "unc-path-regex": "^0.1.2" - } - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, - "is-valid-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", - "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", - "dev": true - }, - "is-valid-path": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-valid-path/-/is-valid-path-0.1.1.tgz", - "integrity": "sha1-EQ+f90w39mPh7HkV60UfLbk6yd8=", - "dev": true, - "requires": { - "is-invalid-path": "^0.1.0" - } - }, - "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 - }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "optional": true, - "requires": { - "is-docker": "^2.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "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 - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "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==", - "dev": true - }, - "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, - "requires": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - } - }, - "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==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "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", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "istextorbinary": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-2.2.1.tgz", - "integrity": "sha512-TS+hoFl8Z5FAFMK38nhBkdLt44CclNRgDHWeMgsV8ko3nDlr/9UI2Sf839sW7enijf8oKsZYXRvM8g0it9Zmcw==", - "dev": true, - "requires": { - "binaryextensions": "2", - "editions": "^1.3.3", - "textextensions": "2" - } - }, - "iterall": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz", - "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==" - }, - "jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz", - "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==", - "dev": true, - "requires": { - "@jest/core": "^26.6.3", - "import-local": "^3.0.2", - "jest-cli": "^26.6.3" - } - }, - "jest-changed-files": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", - "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "execa": "^4.0.0", - "throat": "^5.0.0" - } - }, - "jest-cli": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", - "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", - "dev": true, - "requires": { - "@jest/core": "^26.6.3", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "is-ci": "^2.0.0", - "jest-config": "^26.6.3", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "prompts": "^2.0.1", - "yargs": "^15.4.1" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "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" - } - }, - "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 - }, - "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 - }, - "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 - }, - "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", - "dev": true - }, - "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - } - }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "jest-docblock": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", - "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", - "dev": true, - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", - "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "jest-environment-jsdom": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", - "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", - "dev": true, - "requires": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2", - "jsdom": "^16.4.0" - } - }, - "jest-environment-node": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", - "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", - "dev": true, - "requires": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - } - }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true - }, - "jest-haste-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", - "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.1.2", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^26.0.0", - "jest-serializer": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "micromatch": "^4.0.2", - "sane": "^4.0.3", - "walker": "^1.0.7" - } - }, - "jest-jasmine2": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", - "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", - "dev": true, - "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^26.6.2", - "is-generator-fn": "^2.0.0", - "jest-each": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2", - "throat": "^5.0.0" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "jest-leak-detector": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", - "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", - "dev": true, - "requires": { - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - } - }, - "jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*" - } - }, - "jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "requires": {} - }, - "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true - }, - "jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "jest-resolve-dependencies": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", - "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.6.2" - } - }, - "jest-runner": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", - "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", - "dev": true, - "requires": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.7.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.6.2", - "jest-leak-detector": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "source-map-support": "^0.5.6", - "throat": "^5.0.0" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "jest-runtime": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", - "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", - "dev": true, - "requires": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/globals": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0", - "cjs-module-lexer": "^0.6.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^15.4.1" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "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" - } - }, - "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 - }, - "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 - }, - "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 - }, - "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", - "dev": true - }, - "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - } - }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "jest-serializer": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", - "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", - "dev": true, - "requires": { - "@types/node": "*", - "graceful-fs": "^4.2.4" - } - }, - "jest-snapshot": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", - "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.0.0", - "chalk": "^4.0.0", - "expect": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", - "semver": "^7.3.2" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "jest-validate": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", - "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "camelcase": "^6.0.0", - "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "leven": "^3.1.0", - "pretty-format": "^26.6.2" - }, - "dependencies": { - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "jest-watcher": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", - "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", - "dev": true, - "requires": { - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^26.6.2", - "string-length": "^4.0.1" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - }, - "joi": { - "version": "17.3.0", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.3.0.tgz", - "integrity": "sha512-Qh5gdU6niuYbUIUV5ejbsMiiFmBdw8Kcp8Buj2JntszCkCfxJ9Cz76OtHxOZMPXrt5810iDIXs+n1nNVoquHgg==", - "dev": true, - "requires": { - "@hapi/hoek": "^9.0.0", - "@hapi/topo": "^5.0.0", - "@sideway/address": "^4.1.0", - "@sideway/formula": "^3.0.0", - "@sideway/pinpoint": "^2.0.0" - } - }, - "joiful": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/joiful/-/joiful-3.0.0.tgz", - "integrity": "sha512-NBFIWwN77+fgwwm88dyhcoMceBlaar5y5SVaHJzD7fmM4kvKUsjNh/nU0Bdv9zBYDe57nIPVBdSQXYgOKGHnCQ==", - "dev": true, - "requires": { - "joi": "17.3.0" - } - }, - "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 - }, - "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" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, - "jsdom": { - "version": "16.4.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.4.0.tgz", - "integrity": "sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w==", - "dev": true, - "requires": { - "abab": "^2.0.3", - "acorn": "^7.1.1", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.2.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.0", - "domexception": "^2.0.1", - "escodegen": "^1.14.1", - "html-encoding-sniffer": "^2.0.1", - "is-potential-custom-element-name": "^1.0.0", - "nwsapi": "^2.2.0", - "parse5": "5.1.1", - "request": "^2.88.2", - "request-promise-native": "^1.0.8", - "saxes": "^5.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^3.0.1", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0", - "ws": "^7.2.3", - "xml-name-validator": "^3.0.0" - }, - "dependencies": { - "ws": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.3.tgz", - "integrity": "sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA==", - "dev": true, - "requires": {} - } - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "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==", - "dev": true - }, - "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 - }, - "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=", - "dev": true - }, - "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "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" - } - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "just-debounce": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.0.0.tgz", - "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=", - "dev": true - }, - "kareem": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.1.tgz", - "integrity": "sha512-l3hLhffs9zqoDe8zjmb/mAN4B8VT3L56EUvKNqLFVs9YlFA+zx7ke1DO8STAdDyYNkeSo1nKmjuvQeI12So8Xw==", - "dev": true - }, - "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 - }, - "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true - }, - "knex": { - "version": "0.21.17", - "resolved": "https://registry.npmjs.org/knex/-/knex-0.21.17.tgz", - "integrity": "sha512-kAt58lRwjzqwedApKF7luYPa7HsLb0oDiczwKrkZcekIzTmSow5YGK149S2C8HjH63R3NcOBo9+1rjvWnC1Paw==", - "dev": true, - "requires": { - "colorette": "1.2.1", - "commander": "^6.2.0", - "debug": "4.3.1", - "esm": "^3.2.25", - "getopts": "2.2.5", - "interpret": "^2.2.0", - "liftoff": "3.1.0", - "lodash": "^4.17.20", - "pg-connection-string": "2.4.0", - "tarn": "^3.0.1", - "tildify": "2.0.0", - "v8flags": "^3.2.0" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", - "dev": true - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "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 - } - } - }, - "last-run": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", - "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=", - "dev": true, - "requires": { - "default-resolution": "^2.0.0", - "es6-weak-map": "^2.0.1" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "lead": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", - "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", - "dev": true, - "requires": { - "flush-write-stream": "^1.0.2" - } - }, - "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 - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "libphonenumber-js": { - "version": "1.9.7", - "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.9.7.tgz", - "integrity": "sha512-mDY7fCe6dXd1ZUvYr3Q0ZaoqZ1DVXDSjcqa3AMGyudEd0Tyf8PoHkQ+9NucIBy9C/wFITPwL3Ef9SA148q20Cw==", - "dev": true - }, - "liftoff": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", - "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", - "dev": true, - "requires": { - "extend": "^3.0.0", - "findup-sync": "^3.0.0", - "fined": "^1.0.1", - "flagged-respawn": "^1.0.0", - "is-plain-object": "^2.0.4", - "object.map": "^1.0.0", - "rechoir": "^0.6.2", - "resolve": "^1.1.7" - } - }, - "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=", - "dev": true - }, - "lint-staged": { - "version": "10.5.4", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.4.tgz", - "integrity": "sha512-EechC3DdFic/TdOPgj/RB3FicqE6932LTHCUm0Y2fsD9KGlLB+RwJl2q1IYBIvEsKzDOgn0D4gll+YxG5RsrKg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "cli-truncate": "^2.1.0", - "commander": "^6.2.0", - "cosmiconfig": "^7.0.0", - "debug": "^4.2.0", - "dedent": "^0.7.0", - "enquirer": "^2.3.6", - "execa": "^4.1.0", - "listr2": "^3.2.2", - "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" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "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 - } - } - }, - "listr2": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.2.3.tgz", - "integrity": "sha512-vUb80S2dSUi8YxXahO8/I/s29GqnOL8ozgHVLjfWQXa03BNEeS1TpBLjh2ruaqq5ufx46BRGvfymdBSuoXET5w==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "cli-truncate": "^2.1.0", - "figures": "^3.2.0", - "indent-string": "^4.0.0", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rxjs": "^6.6.3", - "through": "^2.3.8" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "dependencies": { - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.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" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "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.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" - }, - "lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", - "dev": true - }, - "lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "lodash.xorby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.xorby/-/lodash.xorby-4.7.0.tgz", - "integrity": "sha1-nBmm+fBjputT3QPBtocXmYAUY9c=", - "dev": true - }, - "log-symbols": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", - "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", - "dev": true, - "requires": { - "chalk": "^4.0.0" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", - "dev": true, - "requires": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" - }, - "dependencies": { - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - } - } - }, - "loglevel": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz", - "integrity": "sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==", - "dev": true - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - }, - "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==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "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" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "make-fetch-happen": { - "version": "8.0.12", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-8.0.12.tgz", - "integrity": "sha512-cBD7yM72ltWEV+xlLlbimnh5qHwr+thAb/cZLiaZhicVVPVN63BikBvL5OR68+8+z2fvBOgck628vGJ2ulgF6g==", - "dev": true, - "requires": { - "agentkeepalive": "^4.1.3", - "cacache": "^15.0.5", - "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", - "promise-retry": "^1.1.1", - "socks-proxy-agent": "^5.0.0", - "ssri": "^8.0.0" - }, - "dependencies": { - "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" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "make-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", - "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - }, - "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 - } - } - }, - "makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", - "dev": true, - "requires": { - "tmpl": "1.0.x" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "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, - "requires": { - "object-visit": "^1.0.0" - } - }, - "matchdep": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", - "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=", - "dev": true, - "requires": { - "findup-sync": "^2.0.0", - "micromatch": "^3.0.4", - "resolve": "^1.4.0", - "stack-trace": "0.0.10" - }, - "dependencies": { - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": 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, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": 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, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "findup-sync": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^3.1.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - } - }, - "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 - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": 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, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "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 - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": 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" - } - }, - "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=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true - }, - "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==", - "dev": true, - "optional": true - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true - }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "mime-db": { - "version": "1.45.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", - "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==", - "dev": true - }, - "mime-types": { - "version": "2.1.28", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz", - "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==", - "dev": true, - "requires": { - "mime-db": "1.45.0" - } - }, - "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 - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "minipass": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", - "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-fetch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.3.2.tgz", - "integrity": "sha512-/i4fX1ss+Dtwyk++OsAI6SEV+eE1dvI6W+0hORdjfruQ7VD5uYTetJIHcEMjWiEiszWjn2aAtP1CB/Q4KfeoYA==", - "dev": true, - "requires": { - "encoding": "^0.1.12", - "minipass": "^3.1.0", - "minipass-sized": "^1.0.3", - "minizlib": "^2.0.0" - } - }, - "minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-sized": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", - "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "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==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "mongodb": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.3.tgz", - "integrity": "sha512-rOZuR0QkodZiM+UbQE5kDsJykBqWi0CL4Ec2i1nrGrUI3KO11r6Fbxskqmq3JK2NH7aW4dcccBuUujAP0ERl5w==", - "dev": true, - "requires": { - "bl": "^2.2.1", - "bson": "^1.1.4", - "denque": "^1.4.1", - "require_optional": "^1.0.1", - "safe-buffer": "^5.1.2", - "saslprep": "^1.0.0" - } - }, - "mongoose": { - "version": "5.10.18", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.10.18.tgz", - "integrity": "sha512-vaLUzBpUxqacoCqP/xXWMg/uVwCDrlc8LvYjDXCf8hdApvX/CXa0HLa7v2ieFaVd5Fgv3W2QXODLoC4Z/abbNw==", - "dev": true, - "requires": { - "bson": "^1.1.4", - "kareem": "2.3.1", - "mongodb": "3.6.3", - "mongoose-legacy-pluralize": "1.0.2", - "mpath": "0.7.0", - "mquery": "3.2.2", - "ms": "2.1.2", - "regexp-clone": "1.0.0", - "safe-buffer": "5.2.1", - "sift": "7.0.1", - "sliced": "1.0.1" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "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==", - "dev": true - } - } - }, - "mongoose-legacy-pluralize": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz", - "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==", - "dev": true, - "requires": {} - }, - "mpath": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.7.0.tgz", - "integrity": "sha512-Aiq04hILxhz1L+f7sjGyn7IxYzWm1zLNNXcfhDtx04kZ2Gk7uvFdgZ8ts1cWa/6d0TQmag2yR8zSGZUmp0tFNg==", - "dev": true - }, - "mquery": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.2.tgz", - "integrity": "sha512-XB52992COp0KP230I3qloVUbkLUxJIu328HBP2t2EsxSFtf4W1HPSOBWOXf1bqxK4Xbb66lfMJ+Bpfd9/yZE1Q==", - "dev": true, - "requires": { - "bluebird": "3.5.1", - "debug": "3.1.0", - "regexp-clone": "^1.0.0", - "safe-buffer": "5.1.2", - "sliced": "1.0.1" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "mute-stdout": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", - "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", - "dev": true - }, - "mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, - "requires": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "nan": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", - "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": 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" - }, - "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 - } - } - }, - "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 - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "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=", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", - "dev": true - }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", - "dev": true - }, - "node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "dev": true - }, - "node-notifier": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.1.tgz", - "integrity": "sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA==", - "dev": true, - "optional": true, - "requires": { - "growly": "^1.3.0", - "is-wsl": "^2.2.0", - "semver": "^7.3.2", - "shellwords": "^0.1.1", - "uuid": "^8.3.0", - "which": "^2.0.2" - } - }, - "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, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "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 - }, - "now-and-later": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", - "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", - "dev": true, - "requires": { - "once": "^1.3.2" - } - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "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=", - "dev": true - }, - "nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", - "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==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": 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, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "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, - "requires": { - "kind-of": "^3.0.2" - } - }, - "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=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": 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 - } - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-inspect": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", - "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", - "dev": true - }, - "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-path": { - "version": "0.11.5", - "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.5.tgz", - "integrity": "sha512-jgSbThcoR/s+XumvGMTMf81QVBmah+/Q7K7YduKeKVWL7N111unR2d6pZZarSk6kY/caeNxUDyxOvMWyzoU2eg==", - "dev": true - }, - "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, - "requires": { - "isobject": "^3.0.0" - } - }, - "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.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", - "dev": true, - "requires": { - "array-each": "^1.0.1", - "array-slice": "^1.0.0", - "for-own": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", - "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2" - } - }, - "object.map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", - "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", - "dev": true, - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "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, - "requires": { - "isobject": "^3.0.1" - } - }, - "object.reduce": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", - "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=", - "dev": true, - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "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 - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "ordered-read-streams": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", - "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", - "dev": true, - "requires": { - "readable-stream": "^2.0.1" - } - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "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 - }, - "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-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": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "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==", - "dev": true - }, - "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" - } - }, - "parent-require": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parent-require/-/parent-require-1.0.0.tgz", - "integrity": "sha1-dGoWdjgIOoYLDu9nMssn7UbDKXc=", - "dev": true - }, - "parse-filepath": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", - "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", - "dev": true, - "requires": { - "is-absolute": "^1.0.0", - "map-cache": "^0.2.0", - "path-root": "^0.1.1" - } - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "parse-node-version": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", - "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", - "dev": true - }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true - }, - "parse5": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", - "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", - "dev": true - }, - "parse5-htmlparser2-tree-adapter": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", - "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", - "dev": true, - "requires": { - "parse5": "^6.0.1" - }, - "dependencies": { - "parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true - } - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": 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 - }, - "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 - }, - "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=" - }, - "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 - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", - "dev": true, - "requires": { - "path-root-regex": "^0.1.0" - } - }, - "path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", - "dev": true - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", - "dev": true - }, - "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 - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, - "pg": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.5.1.tgz", - "integrity": "sha512-9wm3yX9lCfjvA98ybCyw2pADUivyNWT/yIP4ZcDVpMN0og70BUWYEGXPCTAQdGTAqnytfRADb7NERrY1qxhIqw==", - "dev": true, - "requires": { - "buffer-writer": "2.0.0", - "packet-reader": "1.0.0", - "pg-connection-string": "^2.4.0", - "pg-pool": "^3.2.2", - "pg-protocol": "^1.4.0", - "pg-types": "^2.1.0", - "pgpass": "1.x" - } - }, - "pg-connection-string": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.4.0.tgz", - "integrity": "sha512-3iBXuv7XKvxeMrIgym7njT+HlZkwZqqGX4Bu9cci8xHZNT+Um1gWKqCsAzcC0d95rcKMU5WBg6YRUcHyV0HZKQ==", - "dev": true - }, - "pg-int8": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", - "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", - "dev": true - }, - "pg-pool": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.2.2.tgz", - "integrity": "sha512-ORJoFxAlmmros8igi608iVEbQNNZlp89diFVx6yV5v+ehmpMY9sK6QgpmgoXbmkNaBAx8cOOZh9g80kJv1ooyA==", - "dev": true, - "requires": {} - }, - "pg-protocol": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.4.0.tgz", - "integrity": "sha512-El+aXWcwG/8wuFICMQjM5ZSAm6OWiJicFdNYo+VY3QP+8vI4SvLIWVe51PppTzMhikUJR+PsyIFKqfdXPz/yxA==", - "dev": true - }, - "pg-types": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", - "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", - "dev": true, - "requires": { - "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" - } - }, - "pgpass": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.4.tgz", - "integrity": "sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==", - "dev": true, - "requires": { - "split2": "^3.1.1" - } - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "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=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", - "dev": true, - "requires": { - "node-modules-regexp": "^1.0.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" - } - }, - "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, - "requires": { - "semver-compare": "^1.0.0" - } - }, - "plugin-error": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", - "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", - "dev": true, - "requires": { - "ansi-colors": "^1.0.1", - "arr-diff": "^4.0.0", - "arr-union": "^3.1.0", - "extend-shallow": "^3.0.2" - }, - "dependencies": { - "ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "requires": { - "ansi-wrap": "^0.1.0" - } - } - } - }, - "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 - }, - "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==", - "dev": true - }, - "postgres-bytea": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", - "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=", - "dev": true - }, - "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==", - "dev": true - }, - "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==", - "dev": true, - "requires": { - "xtend": "^4.0.0" - } - }, - "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 - }, - "prettier": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", - "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", - "dev": true - }, - "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - } - }, - "pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "promise-retry": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-1.1.1.tgz", - "integrity": "sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0=", - "dev": true, - "requires": { - "err-code": "^1.0.0", - "retry": "^0.10.0" - }, - "dependencies": { - "retry": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", - "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", - "dev": true - } - } - }, - "prompts": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz", - "integrity": "sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==", - "dev": true, - "requires": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - } - }, - "proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", - "dev": true, - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.1" - } - }, - "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true - }, - "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, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true - }, - "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==", - "dev": true - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "dev": true, - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "dependencies": { - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - }, - "react-is": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", - "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", - "dev": true - }, - "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, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "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 - } - } - }, - "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, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "dependencies": { - "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 - } - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { - "resolve": "^1.1.6" - } - }, - "redis-commands": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz", - "integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==", - "dev": true - }, - "redis-errors": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", - "integrity": "sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=", - "dev": true - }, - "redis-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", - "integrity": "sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=", - "dev": true, - "requires": { - "redis-errors": "^1.0.0" - } - }, - "reflect-metadata": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", - "dev": true - }, - "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, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "regexp-clone": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz", - "integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==", - "dev": true - }, - "remove-bom-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", - "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5", - "is-utf8": "^0.2.1" - } - }, - "remove-bom-stream": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", - "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", - "dev": true, - "requires": { - "remove-bom-buffer": "^3.0.0", - "safe-buffer": "^5.1.0", - "through2": "^2.0.3" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "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 - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": 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 - }, - "replace-ext": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", - "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", - "dev": true - }, - "replace-homedir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", - "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1", - "is-absolute": "^1.0.0", - "remove-trailing-separator": "^1.1.0" - } - }, - "replacestream": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/replacestream/-/replacestream-4.0.3.tgz", - "integrity": "sha512-AC0FiLS352pBBiZhd4VXB1Ab/lh0lEgpP+GGvZqbQh8a5cmXVoTe5EX/YeTFArnp4SRGTHh1qCHu9lGs1qG8sA==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.3", - "object-assign": "^4.0.1", - "readable-stream": "^2.0.2" - } - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - } - } - }, - "request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dev": true, - "requires": { - "lodash": "^4.17.19" - }, - "dependencies": { - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - } - } - }, - "request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "dev": true, - "requires": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - }, - "dependencies": { - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - } - } - }, - "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 - } - } - }, - "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 - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "resolve": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", - "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", - "dev": true, - "requires": { - "is-core-module": "^2.1.0", - "path-parse": "^1.0.6" - } - }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "requires": { - "resolve-from": "^5.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } - } - }, - "resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "resolve-options": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", - "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", - "dev": true, - "requires": { - "value-or-function": "^3.0.0" - } - }, - "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 - }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, - "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 - }, - "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "dev": true - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "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" - } - }, - "rsvp": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", - "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", - "dev": true - }, - "run-parallel": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz", - "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==", - "dev": true - }, - "rxjs": { - "version": "6.6.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz", - "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==", - "dev": true, - "requires": { - "tslib": "^1.9.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 - } - } - }, - "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-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "sane": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", - "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", - "dev": true, - "requires": { - "@cnakazawa/watch": "^1.0.3", - "anymatch": "^2.0.0", - "capture-exit": "^2.0.0", - "exec-sh": "^0.3.2", - "execa": "^1.0.0", - "fb-watchman": "^2.0.0", - "micromatch": "^3.1.4", - "minimist": "^1.1.1", - "walker": "~1.0.5" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": 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, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "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, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": 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, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "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 - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": 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, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "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 - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": 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" - } - }, - "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, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "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, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "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 - }, - "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=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "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" - } - } - } - }, - "saslprep": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", - "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", - "dev": true, - "optional": true, - "requires": { - "sparse-bitfield": "^3.0.3" - } - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true - }, - "saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "requires": { - "xmlchars": "^2.2.0" - } - }, - "semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "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==", - "requires": { - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } - }, - "semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", - "dev": true - }, - "semver-greatest-satisfied-range": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", - "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=", - "dev": true, - "requires": { - "sver-compat": "^1.5.0" - } - }, - "semver-regex": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.2.tgz", - "integrity": "sha512-bXWyL6EAKOJa81XG1OZ/Yyuq+oT0b2YLlxx7c+mrdYPaPbnj6WgVULXhinMIeZGufuUBu/eVRqXEhiv4imfwxA==", - "dev": true - }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - } - } - }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "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, - "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, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "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 - } - } - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "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" - } - }, - "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 - }, - "shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "dev": true, - "optional": true - }, - "sift": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/sift/-/sift-7.0.1.tgz", - "integrity": "sha512-oqD7PMJ+uO6jV9EQCl0LrRw1OwsiPsiFQR5AR30heR+4Dl7jBBbDLnNvWiak20tzZlSE1H7RB30SX/1j/YYT7g==", - "dev": true - }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true - }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "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" - } - }, - "sliced": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", - "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=", - "dev": true - }, - "smart-buffer": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.1.0.tgz", - "integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==", - "dev": true - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": 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" - }, - "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, - "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, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "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, - "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, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "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=", - "dev": 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, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "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 - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "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, - "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, - "requires": { - "is-descriptor": "^1.0.0" - } - } - } - }, - "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, - "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, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "socks": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.5.1.tgz", - "integrity": "sha512-oZCsJJxapULAYJaEYBSzMcz8m3jqgGrHaGhkmU/o/PQfFWYWxkAaA0UMGImb6s6tEXfKi959X6VJjMMQ3P6TTQ==", - "dev": true, - "requires": { - "ip": "^1.1.5", - "smart-buffer": "^4.1.0" - } - }, - "socks-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz", - "integrity": "sha512-lEpa1zsWCChxiynk+lCycKuC502RxDWLKJZoIhnxrWNjLSDGYRFflHA1/228VkRcnv9TIb8w98derGbpKxJRgA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4", - "socks": "^2.3.3" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "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.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "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, - "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-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "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 - } - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "sparkles": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", - "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", - "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=", - "dev": true, - "optional": true, - "requires": { - "memory-pager": "^1.0.2" - } - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "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 - }, - "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, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", - "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", - "dev": true - }, - "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, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "split2": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", - "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", - "dev": true, - "requires": { - "readable-stream": "^3.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" - } - } - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sqlstring": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.2.tgz", - "integrity": "sha512-vF4ZbYdKS8OnoJAWBmMxCQDkiEBkGQYU7UZPtL8flbDRSNkhaXvRJ279ZtI6M+zDaQovVU4tuRgzK5fVhvFAhg==", - "dev": true - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "requires": { - "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" - } - }, - "ssri": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.0.tgz", - "integrity": "sha512-aq/pz989nxVYwn16Tsbj1TqFpD5LLrQxHf5zaHuieFV+R0Bbr4y8qUsOA45hXT/N4/9UNXTarBjnjVmjSOVaAA==", - "dev": true, - "requires": { - "minipass": "^3.1.1" - } - }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", - "dev": true - }, - "stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } - } - }, - "standard-as-callback": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.0.1.tgz", - "integrity": "sha512-NQOxSeB8gOI5WjSaxjBgog2QFw55FV8TkS6Y07BiB3VJ8xNTvUYm0wl0s8ObgQ5NhdpnNfigMIKjgPESzgr4tg==", - "dev": true - }, - "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, - "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, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "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, - "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, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "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=", - "dev": 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, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - } - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - }, - "stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", - "dev": true - }, - "stoppable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", - "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==", - "dev": true - }, - "stream-exhaust": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", - "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", - "dev": true - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "streamsearch": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", - "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "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 - }, - "string-length": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", - "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==", - "dev": true, - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.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" - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "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, - "requires": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.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" - } - }, - "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 - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "subscriptions-transport-ws": { - "version": "0.9.18", - "resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.18.tgz", - "integrity": "sha512-tztzcBTNoEbuErsVQpTN2xUNN/efAZXyCyL5m3x4t6SKrEiTL2N8SaKWBFWM4u56pL79ULif3zjyeq+oV+nOaA==", - "dev": true, - "requires": { - "backo2": "^1.0.2", - "eventemitter3": "^3.1.0", - "iterall": "^1.2.1", - "symbol-observable": "^1.0.4", - "ws": "^5.2.0" - }, - "dependencies": { - "ws": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", - "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", - "dev": true, - "requires": { - "async-limiter": "~1.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" - } - }, - "supports-hyperlinks": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", - "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", - "dev": true, - "requires": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - } - }, - "sver-compat": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", - "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=", - "dev": true, - "requires": { - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" - } - }, - "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==", - "dev": true - }, - "symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true - }, - "tar": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.5.tgz", - "integrity": "sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "tarn": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.1.tgz", - "integrity": "sha512-6usSlV9KyHsspvwu2duKH+FMUhqJnAh6J5J/4MITl8s94iSUQTLkJggdiewKv4RyARQccnigV48Z+khiuVZDJw==", - "dev": true - }, - "terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - } - }, - "test-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, - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - } - }, - "textextensions": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-2.6.0.tgz", - "integrity": "sha512-49WtAWS+tcsy93dRt6P0P3AMD2m5PvXRhuEA0kaXos5ZLlujtYmpmFsB+QvWUSxE1ZsstmYXfQ7L40+EcQgpAQ==", - "dev": true - }, - "thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, - "requires": { - "any-promise": "^1.0.0" - } - }, - "thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", - "dev": true, - "requires": { - "thenify": ">= 3.1.0 < 4" - } - }, - "throat": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - }, - "through2-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", - "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", - "dev": true, - "requires": { - "through2": "~2.0.0", - "xtend": "~4.0.0" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "tildify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz", - "integrity": "sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==", - "dev": true - }, - "time-stamp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", - "dev": true - }, - "tmpl": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", - "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", - "dev": true - }, - "to-absolute-glob": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", - "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", - "dev": true, - "requires": { - "is-absolute": "^1.0.0", - "is-negated-glob": "^1.0.0" - } - }, - "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, - "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, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "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, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.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" - } - }, - "to-through": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", - "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", - "dev": true, - "requires": { - "through2": "^2.0.3" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "dev": true - }, - "tough-cookie": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", - "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", - "dev": true, - "requires": { - "ip-regex": "^2.1.0", - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "tr46": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", - "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", - "dev": true, - "requires": { - "punycode": "^2.1.1" - } - }, - "ts-invariant": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.4.4.tgz", - "integrity": "sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==", - "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 - } - } - }, - "ts-jest": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.2.tgz", - "integrity": "sha512-bwyJ2zJieSugf7RB+o8fgkMeoMVMM2KPDE0UklRLuACxjwJsOrZNo6chrcScmK33YavPSwhARffy8dZx5LJdUQ==", - "dev": true, - "requires": { - "@types/jest": "26.x", - "bs-logger": "0.x", - "buffer-from": "1.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^26.1.0", - "json5": "2.x", - "lodash": "4.x", - "make-error": "1.x", - "mkdirp": "1.x", - "semver": "7.x", - "yargs-parser": "20.x" - } - }, - "ts-node": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", - "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", - "dev": true, - "requires": { - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.17", - "yn": "3.1.1" - } - }, - "tslib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", - "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==" - }, - "tslint": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", - "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^4.0.1", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.3", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.13.0", - "tsutils": "^2.29.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } + "peerDependenciesMeta": { + "@google-cloud/spanner": { + "optional": true + }, + "@sap/hana-client": { + "optional": true + }, + "better-sqlite3": { + "optional": true }, - "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" - } + "hdb-pool": { + "optional": true }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } + "ioredis": { + "optional": true }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "mongodb": { + "optional": 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 + "mssql": { + "optional": true }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "mysql2": { + "optional": true }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } + "oracledb": { + "optional": true }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "pg": { + "optional": true }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } + "pg-native": { + "optional": true }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } - } - }, - "tslint-config-prettier": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", - "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", - "dev": true - }, - "tslint-eslint-rules": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/tslint-eslint-rules/-/tslint-eslint-rules-5.4.0.tgz", - "integrity": "sha512-WlSXE+J2vY/VPgIcqQuijMQiel+UtmXS+4nvK4ZzlDiqBfXse8FAvkNnTcYhnQyOTW5KFM+uRRGXxYhFpuBc6w==", - "dev": true, - "requires": { - "doctrine": "0.7.2", - "tslib": "1.9.0", - "tsutils": "^3.0.0" - }, - "dependencies": { - "tslib": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz", - "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ==", - "dev": true + "pg-query-stream": { + "optional": true + }, + "redis": { + "optional": true + }, + "sql.js": { + "optional": true + }, + "sqlite3": { + "optional": true + }, + "ts-node": { + "optional": true }, - "tsutils": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.20.0.tgz", - "integrity": "sha512-RYbuQuvkhuqVeXweWT3tJLKOEJ/UUw9GjNEZGWdrLLlM+611o1gwLHBpxoFJKKl25fLprp2eVthtKs5JOrNeXg==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } + "typeorm-aurora-data-api-driver": { + "optional": true } } }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "node_modules/typeorm/node_modules/mkdirp": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz", + "integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==", "dev": true, - "requires": { - "tslib": "^1.8.1" + "bin": { + "mkdirp": "dist/cjs/src/bin.js" }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", "dev": true, - "requires": { - "safe-buffer": "^5.0.1" + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" } }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true + "node_modules/typescript-transform-paths": { + "version": "3.4.6", + "resolved": "https://registry.npmjs.org/typescript-transform-paths/-/typescript-transform-paths-3.4.6.tgz", + "integrity": "sha512-qdgpCk9oRHkIBhznxaHAapCFapJt5e4FbFik7Y4qdqtp6VyC3smAIPoDEIkjZ2eiF7x5+QxUPYNwJAtw0thsTw==", + "dev": true, + "dependencies": { + "minimatch": "^3.0.4" + }, + "peerDependencies": { + "typescript": ">=3.6.5" + } }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "node_modules/typescript-transformer-esm": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/typescript-transformer-esm/-/typescript-transformer-esm-1.1.0.tgz", + "integrity": "sha512-MHLIjH9Oa/NJycV1jEyw//3CsLoncqn4ZlURAwqO5TuRQK5rbVklKQJ8dbeBJKgYA6zV8Q7QrKA3Kt9+kk38DQ==", "dev": true, - "requires": { - "prelude-ls": "~1.1.2" + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "typescript": "^4.9.0 || ^5.0.0" } }, - "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==", + "node_modules/typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg==", "dev": true }, - "type-fest": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", - "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "node_modules/uc.micro": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.0.0.tgz", + "integrity": "sha512-DffL94LsNOccVn4hyfRe5rdKa273swqeA5DJpMOeFmEn1wCDc7nAbbB0gXlgBCL7TNzeTv6G7XVWzan7iJtfig==", "dev": true }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "node_modules/ufo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.3.2.tgz", + "integrity": "sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==", "dev": true }, - "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==", + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, - "requires": { - "is-typedarray": "^1.0.0" + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "typedi": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/typedi/-/typedi-0.10.0.tgz", - "integrity": "sha512-v3UJF8xm68BBj6AF4oQML3ikrfK2c9EmZUyLOfShpJuItAqVBHWP/KtpGinkSsIiP6EZyyb6Z3NXyW9dgS9X1w==", - "dev": true + "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" + } }, - "typeorm": { - "version": "0.2.31", - "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.2.31.tgz", - "integrity": "sha512-dVvCEVHH48DG0QPXAKfo0l6ecQrl3A8ucGP4Yw4myz4YEDMProebTQo8as83uyES+nrwCbu3qdkL4ncC2+qcMA==", + "node_modules/unbzip2-stream/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "dev": true, - "requires": { - "@sqltools/formatter": "1.2.2", - "app-root-path": "^3.0.0", - "buffer": "^5.5.0", - "chalk": "^4.1.0", - "cli-highlight": "^2.1.10", - "debug": "^4.1.1", - "dotenv": "^8.2.0", - "glob": "^7.1.6", - "js-yaml": "^3.14.0", - "mkdirp": "^1.0.4", - "reflect-metadata": "^0.1.13", - "sha.js": "^2.4.11", - "tslib": "^1.13.0", - "xml2js": "^0.4.23", - "yargonaut": "^1.1.2", - "yargs": "^16.0.3" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "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 - }, - "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 - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": 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==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "y18n": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", - "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", - "dev": true + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } + { + "type": "consulting", + "url": "https://feross.org/support" } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" } }, - "typeorm-typedi-extensions": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/typeorm-typedi-extensions/-/typeorm-typedi-extensions-0.4.1.tgz", - "integrity": "sha512-05hWktQ4zuXzTTUO3ao56yOezlvUuZhH2NRS//m0SOGCAJoVlfPTMHcmDaMSQy/lMfAwPWoIyn+sfK7ONzTdXQ==", + "node_modules/unconfig": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/unconfig/-/unconfig-0.3.11.tgz", + "integrity": "sha512-bV/nqePAKv71v3HdVUn6UefbsDKQWRX+bJIkiSm0+twIds6WiD2bJLWWT3i214+J/B4edufZpG2w7Y63Vbwxow==", "dev": true, - "requires": {} - }, - "typescript": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.2.tgz", - "integrity": "sha512-tbb+NVrLfnsJy3M59lsDgrzWIflR4d4TIUjz+heUnHZwdF7YsrMTKoRERiIvI2lvBG95dfpLxB21WZhys1bgaQ==", - "dev": true - }, - "unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", - "dev": true - }, - "undertaker": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.3.0.tgz", - "integrity": "sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg==", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "bach": "^1.0.0", - "collection-map": "^1.0.0", - "es6-weak-map": "^2.0.1", - "fast-levenshtein": "^1.0.0", - "last-run": "^1.1.0", - "object.defaults": "^1.0.0", - "object.reduce": "^1.0.0", - "undertaker-registry": "^1.0.0" - }, - "dependencies": { - "fast-levenshtein": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz", - "integrity": "sha1-5qdUzI8V5YmHqpy9J69m/W9OWvk=", - "dev": true - } + "dependencies": { + "@antfu/utils": "^0.7.6", + "defu": "^6.1.2", + "jiti": "^1.20.0", + "mlly": "^1.4.2" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" } }, - "undertaker-registry": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", - "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=", + "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==", "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==", + "node_modules/unique-filename": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, "dependencies": { - "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 - } + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "node_modules/unique-slug": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", "dev": true, - "requires": { - "unique-slug": "^2.0.0" + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "node_modules/unique-string": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", + "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", "dev": true, - "requires": { - "imurmurhash": "^0.1.4" + "dependencies": { + "crypto-random-string": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "unique-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", - "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, - "requires": { - "json-stable-stringify-without-jsonify": "^1.0.1", - "through2-filter": "^3.0.0" + "engines": { + "node": ">= 10.0.0" } }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "node_modules/unpack-string": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/unpack-string/-/unpack-string-0.0.2.tgz", + "integrity": "sha512-2ZFjp5aY7QwHE6HAp47RnKYfvgAQ5+NwbKq/ZVtty85RDb3/UaTeCfizo5L/fXzM7UkMP/zDtbV+kGW/iJiK6w==", "dev": true }, - "unpipe": { + "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } }, - "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, - "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, - "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, - "requires": { - "isarray": "1.0.0" - } - } - } + "node_modules/update-browserslist-db": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", + "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" }, - "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 + { + "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" } }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", - "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "requires": { + "dependencies": { "punycode": "^2.1.0" } }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "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==", + "node_modules/urlpattern-polyfill": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-9.0.0.tgz", + "integrity": "sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==", "dev": true }, - "util-deprecate": { + "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, - "util.promisify": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.1.1.tgz", - "integrity": "sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "for-each": "^0.3.3", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.1" - } - }, - "utils-merge": { + "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true - }, - "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 - }, - "v8-to-istanbul": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.0.tgz", - "integrity": "sha512-uXUVqNUCLa0AH1vuVxzi+MI4RfxEOKt9pBgKwHbgH7st8Kv2P1m+jvWNnektzBh5QShF3ODgKmUFCf38LnVz1g==", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" + "engines": { + "node": ">= 0.4.0" } }, - "v8flags": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", - "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" } }, - "valid-url": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", - "integrity": "sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA=", + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, - "validate-npm-package-license": { + "node_modules/v8-to-istanbul": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "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, - "requires": { + "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, - "validator": { - "version": "13.5.2", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.5.2.tgz", - "integrity": "sha512-mD45p0rvHVBlY2Zuy3F3ESIe1h5X58GPfAtslBjY7EtTqGquZTj+VX/J4RnHWN8FKq0C9WRVt1oWAcytWRuYLQ==", - "dev": true + "node_modules/validator": { + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.9.0.tgz", + "integrity": "sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } }, - "value-or-function": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", - "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", - "dev": true + "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==", + "dev": true, + "engines": { + "node": ">=12" + } }, - "vary": { + "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } }, - "verror": { + "node_modules/verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", "dev": true, - "requires": { + "engines": [ + "node >=0.6.0" + ], + "dependencies": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" } }, - "vinyl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", - "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", + "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==", + "dev": true + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.11.tgz", + "integrity": "sha512-X+8T3GoiwTVlJbicx/sIAF+yuJAqz8VvwJyoMVhwEMoEKE/fkDmrqUgDMyBECcM2A2frVZIUj5HI/ErRXCfOeA==", + "dev": true + }, + "node_modules/vscode-uri": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", + "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==", + "dev": true + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "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==", + "dev": true, + "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==", "dev": true, - "requires": { - "clone": "^2.1.1", - "clone-buffer": "^1.0.0", - "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" + "optional": true, + "peer": true, + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, - "vinyl-fs": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", - "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", - "dev": true, - "requires": { - "fs-mkdirp-stream": "^1.0.0", - "glob-stream": "^6.1.0", - "graceful-fs": "^4.0.0", - "is-valid-glob": "^1.0.0", - "lazystream": "^1.0.0", - "lead": "^1.0.0", - "object.assign": "^4.0.4", - "pumpify": "^1.3.5", - "readable-stream": "^2.3.3", - "remove-bom-buffer": "^3.0.0", - "remove-bom-stream": "^1.2.0", - "resolve-options": "^1.1.0", - "through2": "^2.0.0", - "to-through": "^2.0.0", - "value-or-function": "^3.0.0", - "vinyl": "^2.0.0", - "vinyl-sourcemap": "^1.1.0" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "vinyl-sourcemap": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", - "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", - "dev": true, - "requires": { - "append-buffer": "^1.0.2", - "convert-source-map": "^1.5.0", - "graceful-fs": "^4.1.6", - "normalize-path": "^2.1.1", - "now-and-later": "^2.0.0", - "remove-bom-buffer": "^3.0.0", - "vinyl": "^2.0.0" - }, - "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, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "node_modules/which-collection": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", + "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", "dev": true, - "requires": { - "browser-process-hrtime": "^1.0.0" + "dependencies": { + "is-map": "^2.0.1", + "is-set": "^2.0.1", + "is-weakmap": "^2.0.1", + "is-weakset": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "node_modules/which-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", + "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", "dev": true, - "requires": { - "xml-name-validator": "^3.0.0" + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.4", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "walker": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", - "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "node_modules/wordwrapjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz", + "integrity": "sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw==", "dev": true, - "requires": { - "makeerror": "1.0.x" + "dependencies": { + "reduce-flatten": "^1.0.1", + "typical": "^2.6.1" + }, + "engines": { + "node": ">=4.0.0" } }, - "webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true + "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" + } }, - "whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "node_modules/wrap-ansi-cjs": { + "name": "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": { - "iconv-lite": "0.4.24" + "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" } }, - "whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "node_modules/wrap-ansi-cjs/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==", "dev": true }, - "whatwg-url": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.4.0.tgz", - "integrity": "sha512-vwTUFf6V4zhcPkWp/4CQPr1TW9Ml6SF4lVyaIMBdJw5i6qUUJ1QWM4Z6YYVkfka0OUIzVo/0aNtGVGk256IKWw==", + "node_modules/wrap-ansi-cjs/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==", "dev": true, - "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^2.0.2", - "webidl-conversions": "^6.1.0" + "engines": { + "node": ">=8" } }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "node_modules/wrap-ansi-cjs/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==", "dev": true, - "requires": { - "isexe": "^2.0.0" + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", - "dev": true - }, - "which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", + "node_modules/wrap-ansi/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==", "dev": true }, - "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 + "node_modules/wrap-ansi/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==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "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==", + "node_modules/wrap-ansi/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==", "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "wrappy": { + "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true }, - "write-file-atomic": { + "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, - "requires": { + "dependencies": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", "signal-exit": "^3.0.2", "typedarray-to-buffer": "^3.1.5" } }, - "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "node_modules/write-file-atomic/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/xdg-basedir": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", + "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", "dev": true, - "requires": { - "async-limiter": "~1.0.0" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } }, - "xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "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, - "requires": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" + "engines": { + "node": ">=10" } }, - "xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "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==" }, - "xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true + "node_modules/yaml": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", + "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", + "dev": true, + "engines": { + "node": ">= 14" + } }, - "xss": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.8.tgz", - "integrity": "sha512-3MgPdaXV8rfQ/pNn16Eio6VXYPTkqwa0vc7GkiymmY/DqR1SE/7VPAAVZz1GJsJFrllMYO3RHfEaiUGjab6TNw==", + "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, - "requires": { - "commander": "^2.20.3", - "cssfilter": "0.0.10" - }, "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } + "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" } }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true + "node_modules/yargs-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha512-WhzC+xgstid9MbVUktco/bf+KJG+Uu6vMX0LN1sLJvwmbCQVxb4D8LzogobonKycNasCZLdOzTAk1SK7+K7swg==", + "dev": true, + "dependencies": { + "camelcase": "^4.1.0" + } }, - "y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true + "node_modules/yargs-parser/node_modules/camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==", + "dev": true, + "engines": { + "node": ">=4" + } }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "node_modules/yargs/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==", "dev": true }, - "yaml": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", - "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==", - "dev": true + "node_modules/yargs/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==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "yargonaut": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/yargonaut/-/yargonaut-1.1.4.tgz", - "integrity": "sha512-rHgFmbgXAAzl+1nngqOcwEljqHGG9uUZoPjsdZEs1w5JW9RXYzrSvH/u70C1JE5qFi0qjsdhnUX/dJRpWqitSA==", + "node_modules/yargs/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==", "dev": true, - "requires": { - "chalk": "^1.1.1", - "figlet": "^1.1.1", - "parent-require": "^1.0.0" - }, "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "yargs": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.1.tgz", - "integrity": "sha512-huO4Fr1f9PmiJJdll5kwoS2e4GqzGSsMT3PPMpOwoVkOK8ckqAewMTZyA6LXVQWflleb/Z8oPBEvNsMft0XE+g==", + "node_modules/yargs/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, - "requires": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "y18n": "^3.2.1", - "yargs-parser": "5.0.0-security.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "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=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "yargs-parser": { - "version": "5.0.0-security.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0-security.0.tgz", - "integrity": "sha512-T69y4Ps64LNesYxeYGYPvfoMTt/7y1XtfpIslUeK4um+9Hu7hlGoRtaDLvdXb7+/tfq4opVa2HRY5xGip022rQ==", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "object.assign": "^4.1.0" - } - } + "engines": { + "node": ">=12" } }, - "yargs-parser": { - "version": "20.2.6", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.6.tgz", - "integrity": "sha512-AP1+fQIWSM/sMiET8fyayjx/J+JmTPt2Mr0FkrgqB4todtfa53sOsrSAcIrJRD5XS20bKUwaDIuMkWKCEiQLKA==", - "dev": true + "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" + } }, - "yn": { + "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "yocto-queue": { + "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==", - "dev": true - }, - "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 - }, - "zen-observable-ts": { - "version": "0.8.21", - "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.8.21.tgz", - "integrity": "sha512-Yj3yXweRc8LdRMrCC8nIc4kkjWecPAUVh0TI0OUrWXx6aX790vLcDlWca6I4vsyCGH3LpWxq0dJRcMOFoVqmeg==", "dev": true, - "requires": { - "tslib": "^1.9.3", - "zen-observable": "^0.8.0" + "engines": { + "node": ">=10" }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } } } diff --git a/package.json b/package.json index b5d8aacf6..a89d8c227 100644 --- a/package.json +++ b/package.json @@ -1,131 +1,195 @@ { "name": "type-graphql", - "version": "0.0.0-unreleased", - "author": { - "name": "MichaΕ‚ Lytek", - "url": "https://github.com/MichalLytek" + "version": "2.0.0-rc.1", + "private": false, + "description": "Create GraphQL schema and resolvers with TypeScript, using classes and decorators!", + "keywords": [ + "typescript", + "graphql", + "schema", + "resolvers", + "api", + "decorators", + "controllers", + "apollo" + ], + "homepage": "https://typegraphql.com", + "bugs": { + "url": "https://github.com/MichalLytek/type-graphql/issues" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/MichalLytek/type-graphql.git" }, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/TypeGraphQL" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/typegraphql" + } + ], + "license": "MIT", + "author": "MichaΕ‚ Lytek (https://github.com/MichalLytek)", + "exports": { + ".": { + "require": "./build/cjs/index.js", + "import": "./build/esm/index.js", + "types": "./build/typings/index.d.ts" + }, + "./shim": { + "require": "./build/cjs/shim.js", + "import": "./build/esm/shim.js", + "types": "./build/typings/shim.ts" + } + }, + "main": "./build/cjs/index.js", + "module": "./build/esm/index.js", + "browser": "./build/cjs/shim.js", + "types": "./build/typings/index.d.ts", + "files": [ + "./build" + ], "scripts": { - "test": "jest --verbose --coverage", - "test:ci": "jest --verbose --coverage --ci --forceExit --detectOpenHandles --runInBand", - "test:watch": "jest --watch", - "format": "prettier --write \"{src,tests,examples}/**/*.{ts,js}\" \"docs/**/*.md\"", - "check:format": "prettier --check \"{src,tests,examples}/**/*.{ts,js}\" \"docs/**/*.md\"", - "check:type": "tsc --noEmit && tsc --noEmit -p ./examples/tsconfig.json", - "check": "npm run check:format && npm run check:type", - "lint": "tslint --project tsconfig.json", - "verify": "npm run check && npm run lint", - "package": "gulp package", - "docs": "npm run --prefix website start", - "postinstall": "node ./dist/postinstall || exit 0" + "prebuild": "npm run clean:build && npm run check:version", + "build": "npx tsc --build ./tsconfig.cjs.json ./tsconfig.esm.json ./tsconfig.typings.json", + "postbuild": "npx shx rm ./build/typings/shim.d.ts && npx shx cp ./src/shim.ts ./build/typings && npx ts-node ./scripts/package.json.ts", + "prebuild:benchmarks": "npm run clean:build:benchmarks", + "build:benchmarks": "npx tsc --build ./benchmarks/tsconfig.json", + "check": "npx npm-run-all --npm-path npm \"check:*\"", + "check:benchmarks": "npx tsc --project ./benchmarks/tsconfig.json --noEmit", + "check:examples": "npx tsc --project ./examples/tsconfig.json --noEmit", + "check:format": "npx prettier --check .", + "check:lint": "npx eslint .", + "check:markdown": "npx markdownlint \"**/*.md\"", + "check:script": "npx shellcheck ./.husky/pre-commit", + "check:scripts": "npx tsc --project ./scripts/tsconfig.json --noEmit", + "check:spell": "npx cspell lint --config cspell.json --no-progress --show-context \"**\"", + "check:type": "npx npm-run-all --npm-path npm \"check:type:*\"", + "check:type:cjs": "npx tsc --project ./tsconfig.cjs.json --noEmit", + "check:type:esm": "npx tsc --project ./tsconfig.esm.json --noEmit", + "check:type:tests": "npx tsc --project ./tests/tsconfig.json --noEmit", + "check:type:typings": "npx tsc --project ./tsconfig.typings.json --noEmit --emitDeclarationOnly false", + "check:version": "npx ts-node ./scripts/version.ts", + "clean": "npx npm-run-all --npm-path npm \"clean:*\"", + "clean:build": "npx shx rm -rf ./build", + "clean:build:benchmarks": "npx shx rm -rf ./benchmarks/build", + "clean:coverage": "npx shx rm -rf ./coverage", + "prepublishOnly": "npm run build && npm run gen:readme", + "pretest": "npm run clean:coverage", + "test": "npx jest --verbose --coverage", + "test:watch": "npx jest --watch", + "pretest:ci": "npm run clean:coverage", + "test:ci": "npx jest --verbose --coverage --ci --forceExit --runInBand", + "release": "npm version --message \"release: %s\"", + "version": "npm run --prefix ./website new-release --release=$npm_package_version && git add -A .", + "docs": "npm run start --prefix website", + "fix": "npx npm-run-all --npm-path npm \"fix:*\"", + "fix:format": "npx prettier --write .", + "fix:lint": "npx eslint --fix .", + "fix:markdown": "npx markdownlint --fix \"**/*.md\"", + "gen:docs": "npx ts-node ./scripts/markdown.ts --on docs", + "gen:readme": "npx ts-node ./scripts/markdown.ts --on readme", + "gen:sponsorkit": "npx sponsorkit --width=320 --dir=./images --name=github-sponsors", + "postgen:sponsorkit": "npx shx cp ./images/github-sponsors.svg ./website/static/img/github-sponsors.svg", + "prepare": "npx ts-patch install -s && npx husky install" }, "peerDependencies": { - "class-validator": ">=0.12.0", - "graphql": "^15.5.0" + "class-validator": ">=0.14.0", + "graphql": "^16.8.1", + "graphql-scalars": "^1.22.4" + }, + "peerDependenciesMeta": { + "class-validator": { + "optional": true + } }, "dependencies": { - "@types/glob": "^7.1.3", + "@graphql-yoga/subscription": "^5.0.0", "@types/node": "*", - "@types/semver": "^7.3.4", - "glob": "^7.1.6", - "graphql-query-complexity": "^0.7.2", - "graphql-subscriptions": "^1.2.0", - "semver": "^7.3.4", - "tslib": "^2.1.0" + "@types/semver": "^7.5.6", + "graphql-query-complexity": "^0.12.0", + "semver": "^7.5.4", + "tslib": "^2.6.2" }, "devDependencies": { - "@apollo/federation": "^0.21.2", - "@apollo/gateway": "^0.23.2", - "@graphql-modules/core": "^0.7.13", - "@graphql-modules/di": "^0.7.17", - "@mikro-orm/core": "^4.4.4", - "@mikro-orm/postgresql": "^4.4.4", - "@typegoose/typegoose": "^7.4.8", - "@types/gulp": "^4.0.8", - "@types/gulp-replace": "0.0.31", - "@types/ioredis": "^4.22.0", - "@types/jest": "^26.0.20", - "@types/mongoose": "^5.10.3", - "@types/node": "^14.14.31", - "@types/rimraf": "^3.0.0", - "apollo-cache-control": "^0.11.6", - "apollo-server": "^2.21.0", - "apollo-server-plugin-response-cache": "^0.6.0", - "class-validator": "^0.13.1", - "del": "^6.0.0", - "graphql": "^15.5.0", - "graphql-redis-subscriptions": "^2.3.1", - "graphql-tag": "^2.11.0", - "gulp-replace": "^1.0.0", - "gulp-shell": "^0.8.0", - "gulp-typescript": "^5.0.1", - "gulpclass": "^0.2.0", - "husky": "^4.3.8", - "ioredis": "^4.23.0", - "jest": "^26.6.3", - "joiful": "^3.0.0", - "lint-staged": "^10.5.4", - "mongoose": "5.10.18", - "pg": "^8.5.1", - "prettier": "^2.2.1", + "@apollo/cache-control-types": "^1.0.3", + "@apollo/gateway": "^2.7.1", + "@apollo/server": "^4.10.0", + "@apollo/server-plugin-response-cache": "^4.1.3", + "@apollo/subgraph": "^2.7.1", + "@cspell/dict-node": "^4.0.3", + "@cspell/dict-npm": "^5.0.14", + "@cspell/dict-shell": "^1.0.6", + "@cspell/dict-typescript": "^3.1.2", + "@cspell/eslint-plugin": "^8.3.2", + "@graphql-tools/schema": "^10.0.2", + "@graphql-tools/utils": "^10.1.2", + "@graphql-yoga/redis-event-target": "^3.0.0", + "@mikro-orm/core": "^6.0.2", + "@mikro-orm/postgresql": "^6.2.1", + "@typegoose/typegoose": "^12.2.0", + "@types/jest": "^29.5.11", + "@types/lodash.merge": "^4.6.9", + "@types/node": "^20.11.24", + "@types/shelljs": "^0.8.15", + "@types/yargs": "^17.0.32", + "@typescript-eslint/eslint-plugin": "^6.18.1", + "@typescript-eslint/parser": "^6.18.1", + "class-validator": "^0.14.0", + "cspell": "^8.7.0", + "dotenv": "^16.4.5", + "eslint": "^8.56.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-airbnb-typescript": "^17.1.0", + "eslint-config-prettier": "^9.1.0", + "eslint-import-resolver-typescript": "^3.6.1", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-jest": "^27.6.2", + "eslint-plugin-tsdoc": "^0.2.17", + "expect": "^29.7.0", + "glob": "^10.3.10", + "graphql": "^16.8.1", + "graphql-scalars": "^1.22.4", + "graphql-tag": "^2.12.6", + "graphql-yoga": "^5.1.1", + "husky": "^8.0.3", + "ioredis": "^5.3.2", + "jest": "^29.7.0", + "joiful": "^3.0.2", + "lint-staged": "^15.2.0", + "lodash.merge": "^4.6.2", + "markdownlint": "^0.33.0", + "markdownlint-cli": "^0.38.0", + "mongoose": "^8.0.4", + "npm-run-all": "^4.1.5", + "pg": "^8.11.3", + "prettier": "^3.2.5", + "prettier-plugin-sh": "^0.14.0", "reflect-metadata": "^0.1.13", - "rimraf": "^3.0.2", - "ts-jest": "^26.5.2", - "ts-node": "^9.1.1", - "tslint": "^6.1.3", - "tslint-config-prettier": "^1.18.0", - "tslint-eslint-rules": "^5.4.0", + "shellcheck": "^2.2.0", + "shelljs": "^0.8.5", + "shx": "^0.3.4", + "sponsorkit": "^0.9.1", + "ts-jest": "^29.1.1", + "ts-node": "^10.9.2", + "ts-patch": "^3.1.1", + "tsconfig-paths": "^4.2.0", + "tsyringe": "^4.8.0", "typedi": "^0.10.0", - "typeorm": "^0.2.31", - "typeorm-typedi-extensions": "^0.4.1", - "typescript": "~4.2.2" - }, - "husky": { - "hooks": { - "pre-commit": "lint-staged" - } - }, - "lint-staged": { - "{src,tests,examples}/**/*.ts": [ - "tslint --fix", - "prettier --write" - ], - "{src,tests,examples}/**/*.js": [ - "prettier --write" - ], - "docs/**/*.md": [ - "prettier --write" - ] - }, - "main": "./dist/index.js", - "browser": "./dist/browser-shim.js", - "types": "./dist/index.d.ts", - "readmeFilename": "README.md", - "description": "Create GraphQL schema and resolvers with TypeScript, using classes and decorators!", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typegraphql" - }, - "repository": { - "type": "git", - "url": "https://github.com/MichalLytek/type-graphql.git" + "typeorm": "^0.3.19", + "typescript": "^5.3.3", + "typescript-transform-paths": "^3.4.6", + "typescript-transformer-esm": "^1.1.0", + "yargs": "^17.7.2" }, - "bugs": { - "url": "https://github.com/MichalLytek/type-graphql/issues" - }, - "keywords": [ - "typescript", - "graphql", - "schema", - "resolvers", - "api", - "decorators", - "controllers", - "apollo" - ], "engines": { - "node": ">= 10.13" + "node": ">= 18.12.0" }, - "private": true + "publishConfig": { + "access": "public", + "provenance": true + } } diff --git a/publish-website.sh b/publish-website.sh deleted file mode 100644 index ac0c964c6..000000000 --- a/publish-website.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -e - -if [ "$TRAVIS_PULL_REQUEST" = "false" ] && [ "$TRAVIS_BRANCH" = "master" ]; then - git config user.email "$GIT_USER@users.noreply.github.com" - git config user.name "Travis" - echo "machine github.com login $GIT_USER password $GIT_TOKEN" > ~/.netrc - - cd website - npm install - GIT_USER=$GIT_USER CURRENT_BRANCH=master npm run publish-gh-pages - exit 0; -fi diff --git a/scripts/.eslintrc b/scripts/.eslintrc new file mode 100644 index 000000000..d26406272 --- /dev/null +++ b/scripts/.eslintrc @@ -0,0 +1,10 @@ +{ + "rules": { + "import/no-extraneous-dependencies": [ + "error", + { + "devDependencies": true + } + ] + } +} diff --git a/scripts/markdown.ts b/scripts/markdown.ts new file mode 100644 index 000000000..2c0b6bb73 --- /dev/null +++ b/scripts/markdown.ts @@ -0,0 +1,125 @@ +#!/usr/bin/env ts-node + +import fs from "node:fs"; +import path from "node:path"; +import * as glob from "glob"; +import { hideBin } from "yargs/helpers"; +import yargs from "yargs/yargs"; + +function toUrlPath( + filePath: string, + relativePath: string, + rootPath: string, + basePath: string, +): string { + return path.resolve(path.dirname(filePath), relativePath).replace(rootPath, basePath); +} + +function escapeRegExp(string: string): string { + return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); +} + +const enum Analyze { + DOCS = "docs", + README = "readme", +} + +const gitHubUrl = `https://github.com/MichalLytek/type-graphql/tree`; +const gitHubUrlRaw = `https://raw.githubusercontent.com/MichalLytek/type-graphql`; +const rootPath = path.resolve(`${__dirname}/..`); +const argv = yargs(hideBin(process.argv)) + .strict() + .env("TYPE_GRAPHQL") + .usage("Markdown\n\nUsage: $0 --ref [options]") + .example([ + ["$0 --ref v1.2.3", "Use 'v1.2.3' as Git reference"], + ["TYPE_GRAPHQL_REF=v1.2.3 $0", "Use 'v1.2.3' as Git reference"], + [ + `$0 --ref v1.2.3 --on ${Analyze.README}`, + `Use 'v1.2.3' as Git reference and analyze '${Analyze.README}'`, + ], + [ + `$0 --ref v1.2.3 --on ${Analyze.README} ${Analyze.DOCS}`, + `Use 'v1.2.3' as Git reference and analyze '${Analyze.README}' and '${Analyze.DOCS}'`, + ], + ]) + .option("ref", { + type: "string", + demandOption: true, + description: "Git reference", + }) + .option("on", { + type: "array", + default: [] as Analyze[], + requiresArg: true, + choices: [Analyze.DOCS, Analyze.README], + description: "Analysis to be performed", + }) + .check(({ ref, on }) => { + if ( + !/^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-(alpha|beta|rc)\.(0|[1-9][0-9]*))?$/.test( + ref, + ) + ) { + throw new Error(`Invalid Git reference '${ref}'`); + } + if (on.length === 0) { + throw new Error(`Empty analysis`); + } + + return true; + }) + .parseSync(); +const gitHubUrlRef = `${gitHubUrl}/${argv.ref}`; +const gitHubUrlRawRef = `${gitHubUrlRaw}/${argv.ref}`; + +// README.md +if (argv.on.includes(Analyze.README)) { + const readmeFile = path.resolve(`${rootPath}/README.md`); + + const readme = fs + .readFileSync(readmeFile, { encoding: "utf8", flag: "r" }) + .replace( + /!\[([^\]]*)\]\(((?:\.\/|\.\.\/).*?)\)/gm, // ![altText](relativePath) + (_, altText, relativePath) => + `![${altText}](${toUrlPath(readmeFile, relativePath, rootPath, gitHubUrlRawRef)})`, + ) + .replace( + /]*)\ssrc="((?:\.\/|\.\.\/)[^">]+)"/gm, // + ` + `[${linkText}](${toUrlPath(readmeFile, relativePath, rootPath, gitHubUrlRef)})`, + ) + .replace( + /]*)\shref="((?:\.\/|\.\.\/)[^">]+)"/gm, // + ` `[${linkText}](${gitHubUrlRef}/${relativePath})`, + ) + .replace( + new RegExp(`]*)\\shref="${gitHubUrlRefMasterEscaped}\\/?([^">]+)"`, "gm"), // ` & { raw: { include: string[] } }; + +function readTsConfig(fileName: string): TsConfig { + const config = typescript.readConfigFile(fileName, typescript.sys.readFile); + expect(config.config).toBeDefined(); + expect(config.error).toBeUndefined(); + + const configJson = typescript.parseJsonConfigFileContent( + config.config, + typescript.sys, + path.dirname(fileName), + ); + expect(configJson.options.outDir).toBeDefined(); + expect(configJson.raw.include).toBeDefined(); + expect(Array.isArray(configJson.raw.include)).toBeTruthy(); + expect(configJson.raw.include.length).toBeGreaterThanOrEqual(1); + + return configJson as TsConfig; +} + +function writePackageJson(fileName: string, fileContent: string | NodeJS.ArrayBufferView): void { + const fileBasename = path.basename(fileName); + const fileDirname = path.dirname(fileName); + + expect(fileBasename).toBe("package.json"); + if (!fs.existsSync(fileDirname)) { + throw new Error(`Directory '${fileDirname}' does not exists`); + } + if (fs.existsSync(fileName)) { + throw new Error(`File '${fileName}' already exists`); + } + + fs.writeFileSync(fileName, fileContent, { + encoding: "utf8", + flag: "w", + }); +} + +const packageJson = JSON.stringify({ type: "module" }); +const tsconfigRoot = readTsConfig(path.resolve(__dirname, "../tsconfig.esm.json")); +const packageJsonRoot = path.resolve(`${tsconfigRoot.options.outDir}/package.json`); + +writePackageJson(packageJsonRoot, packageJson); diff --git a/scripts/tsconfig.json b/scripts/tsconfig.json new file mode 100644 index 000000000..e6b246ba9 --- /dev/null +++ b/scripts/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "noEmit": true + }, + "include": [".", "../src"] +} diff --git a/scripts/version.ts b/scripts/version.ts new file mode 100644 index 000000000..f9dbdbf21 --- /dev/null +++ b/scripts/version.ts @@ -0,0 +1,10 @@ +#!/usr/bin/env ts-node + +import packageJson from "../package.json"; +import { graphQLPeerDependencyVersion } from "../src/utils/graphql-version"; + +if (graphQLPeerDependencyVersion !== packageJson.peerDependencies.graphql) { + throw new Error( + `GraphQL peer dependency version (${graphQLPeerDependencyVersion}) != package.json.peerDependencies.graphql (${packageJson.peerDependencies.graphql})`, + ); +} diff --git a/sponsorkit.config.ts b/sponsorkit.config.ts new file mode 100644 index 000000000..09e861292 --- /dev/null +++ b/sponsorkit.config.ts @@ -0,0 +1,117 @@ +import { BadgePreset, defineConfig } from "sponsorkit"; + +const presets = { + past: { + avatar: { + size: 20, + }, + boxWidth: 25, + boxHeight: 25, + container: { + sidePadding: 30, + }, + }, + backers: { + avatar: { + size: 30, + }, + boxWidth: 35, + boxHeight: 35, + container: { + sidePadding: 30, + }, + }, + members: { + avatar: { + size: 45, + }, + boxWidth: 55, + boxHeight: 55, + container: { + sidePadding: 30, + }, + }, + bronze: { + avatar: { + size: 75, + }, + boxWidth: 90, + boxHeight: 100, + container: { + sidePadding: 20, + }, + name: { + maxLength: 10, + }, + }, + silver: { + avatar: { + size: 100, + }, + boxWidth: 105, + boxHeight: 125, + container: { + sidePadding: 20, + }, + name: { + maxLength: 16, + }, + }, + gold: { + avatar: { + size: 150, + }, + boxWidth: 175, + boxHeight: 175, + container: { + sidePadding: 20, + }, + name: { + maxLength: 20, + }, + }, +} satisfies Record; + +export default defineConfig({ + includePastSponsors: true, + formats: ["svg"], + github: { + login: "TypeGraphQL", + type: "organization", + }, + // opencollective: { + // type: "collective", + // slug: "typegraphql", + // }, + tiers: [ + { + title: "Past Sponsors ⏳", + monthlyDollars: -1, + preset: presets.past, + }, + { + title: "Backers β˜•", + preset: presets.backers, + }, + { + title: "Members πŸ’ͺ", + monthlyDollars: 15, + preset: presets.members, + }, + { + title: "Bronze Sponsors πŸ₯‰", + monthlyDollars: 50, + preset: presets.bronze, + }, + { + title: "Silver Sponsors πŸ₯ˆ", + monthlyDollars: 100, + preset: presets.silver, + }, + { + title: "Gold Sponsors πŸ†", + monthlyDollars: 300, + preset: presets.gold, + }, + ], +}); diff --git a/src/@types/Reflect.d.ts b/src/@types/Reflect.d.ts new file mode 100644 index 000000000..d5da27d66 --- /dev/null +++ b/src/@types/Reflect.d.ts @@ -0,0 +1,51 @@ +// Copied from 'reflect-metadata' (https://github.com/rbuckton/reflect-metadata/blob/master/index.d.ts) + +/*! ***************************************************************************** +Copyright (C) Microsoft. All rights reserved. +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at http://www.apache.org/licenses/LICENSE-2.0 + +THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED +WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, +MERCHANTABILITY OR NON-INFRINGEMENT. + +See the Apache Version 2.0 License for specific language governing permissions +and limitations under the License. +***************************************************************************** */ + +declare namespace Reflect { + function getMetadata(metadataKey: any, target: object): any; + /** + * Gets the metadata value for the provided metadata key on the target object or its prototype chain. + * @param metadataKey - A key used to store and retrieve metadata. + * @param target - The target object on which the metadata is defined. + * @param propertyKey - The property key for the target. + * @returns The metadata value for the metadata key if found; otherwise, `undefined`. + * @example + * + * class Example \{ + * // property declarations are not part of ES6, though they are valid in TypeScript: + * // static staticProperty; + * // property; + * + * static staticMethod(p) \{ \} + * method(p) \{ \} + * \} + * + * // property (on constructor) + * result = Reflect.getMetadata("custom:annotation", Example, "staticProperty"); + * + * // property (on prototype) + * result = Reflect.getMetadata("custom:annotation", Example.prototype, "property"); + * + * // method (on constructor) + * result = Reflect.getMetadata("custom:annotation", Example, "staticMethod"); + * + * // method (on prototype) + * result = Reflect.getMetadata("custom:annotation", Example.prototype, "method"); + * + */ + function getMetadata(metadataKey: any, target: object, propertyKey: string | symbol): any; +} diff --git a/src/declarations.d.ts b/src/declarations.d.ts deleted file mode 100644 index 0d228a413..000000000 --- a/src/declarations.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -// definitions copied from `reflect-metadata` to satisfy gulp-typescript -declare namespace Reflect { - function getMetadata(metadataKey: any, target: Object): any; - function getMetadata(metadataKey: any, target: Object, propertyKey: string | symbol): any; - function decorate(decorators: ClassDecorator[], target: Function): Function; - function decorate( - decorators: Array, - target: Object, - propertyKey: string | symbol, - attributes?: PropertyDescriptor, - ): PropertyDescriptor; - function metadata( - metadataKey: any, - metadataValue: any, - ): { - (target: Function): void; - (target: Object, propertyKey: string | symbol): void; - }; -} - -declare namespace NodeJS { - interface Global { - TypeGraphQLMetadataStorage: import("../src/metadata/metadata-storage").MetadataStorage; - } -} diff --git a/src/decorators/Arg.ts b/src/decorators/Arg.ts index e7c4f9e7c..50bad778e 100644 --- a/src/decorators/Arg.ts +++ b/src/decorators/Arg.ts @@ -1,13 +1,14 @@ +import { getTypeDecoratorParams } from "@/helpers/decorators"; +import { getParamInfo } from "@/helpers/params"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { type ParameterDecorator } from "@/typings"; import { - ReturnTypeFunc, - DecoratorTypeOptions, - DescriptionOptions, - ValidateOptions, - DeprecationOptions, + type DecoratorTypeOptions, + type DeprecationOptions, + type DescriptionOptions, + type ReturnTypeFunc, + type ValidateOptions, } from "./types"; -import { getMetadataStorage } from "../metadata/getMetadataStorage"; -import { getParamInfo } from "../helpers/params"; -import { getTypeDecoratorParams } from "../helpers/decorators"; export type ArgOptions = DecoratorTypeOptions & DescriptionOptions & diff --git a/src/decorators/Args.ts b/src/decorators/Args.ts index 464ec5f0a..372a35ea9 100644 --- a/src/decorators/Args.ts +++ b/src/decorators/Args.ts @@ -1,7 +1,8 @@ -import { getMetadataStorage } from "../metadata/getMetadataStorage"; -import { getParamInfo } from "../helpers/params"; -import { ValidateOptions, ReturnTypeFunc } from "./types"; -import { getTypeDecoratorParams } from "../helpers/decorators"; +import { getTypeDecoratorParams } from "@/helpers/decorators"; +import { getParamInfo } from "@/helpers/params"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { type ParameterDecorator } from "@/typings"; +import { type ReturnTypeFunc, type ValidateOptions } from "./types"; export function Args(): ParameterDecorator; export function Args(options: ValidateOptions): ParameterDecorator; diff --git a/src/decorators/ArgsType.ts b/src/decorators/ArgsType.ts index 412bd1717..6da327d31 100644 --- a/src/decorators/ArgsType.ts +++ b/src/decorators/ArgsType.ts @@ -1,4 +1,4 @@ -import { getMetadataStorage } from "../metadata/getMetadataStorage"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; export function ArgsType(): ClassDecorator { return target => { diff --git a/src/decorators/Authorized.ts b/src/decorators/Authorized.ts index 80a1504cf..609860875 100644 --- a/src/decorators/Authorized.ts +++ b/src/decorators/Authorized.ts @@ -1,7 +1,7 @@ -import { getMetadataStorage } from "../metadata/getMetadataStorage"; -import { SymbolKeysNotSupportedError } from "../errors"; -import { getArrayFromOverloadedRest } from "../helpers/decorators"; -import { MethodAndPropDecorator } from "./types"; +import { SymbolKeysNotSupportedError } from "@/errors"; +import { getArrayFromOverloadedRest } from "@/helpers/decorators"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { type MethodAndPropDecorator } from "./types"; export function Authorized(): MethodAndPropDecorator; export function Authorized(roles: readonly RoleType[]): MethodAndPropDecorator; @@ -13,7 +13,7 @@ export function Authorized( ): MethodDecorator | PropertyDecorator { const roles = getArrayFromOverloadedRest(rolesOrRolesArray); - return (prototype, propertyKey, descriptor) => { + return (prototype, propertyKey, _descriptor) => { if (typeof propertyKey === "symbol") { throw new SymbolKeysNotSupportedError(); } diff --git a/src/decorators/Ctx.ts b/src/decorators/Ctx.ts index 47332cb36..9b20207d0 100644 --- a/src/decorators/Ctx.ts +++ b/src/decorators/Ctx.ts @@ -1,5 +1,6 @@ -import { getMetadataStorage } from "../metadata/getMetadataStorage"; -import { SymbolKeysNotSupportedError } from "../errors"; +import { SymbolKeysNotSupportedError } from "@/errors"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { type ParameterDecorator } from "@/typings"; export function Ctx(propertyName?: string): ParameterDecorator { return (prototype, propertyKey, parameterIndex) => { diff --git a/src/decorators/Directive.ts b/src/decorators/Directive.ts index 767705c5e..cd7fced58 100644 --- a/src/decorators/Directive.ts +++ b/src/decorators/Directive.ts @@ -1,23 +1,38 @@ -import { MethodAndPropDecorator } from "./types"; -import { SymbolKeysNotSupportedError } from "../errors"; -import { getMetadataStorage } from "../metadata/getMetadataStorage"; +import { SymbolKeysNotSupportedError } from "@/errors"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { type MethodAndPropDecorator } from "./types"; -export function Directive(sdl: string): MethodAndPropDecorator & ClassDecorator; +export function Directive( + sdl: string, +): MethodAndPropDecorator & ClassDecorator & ParameterDecorator; export function Directive( nameOrDefinition: string, -): MethodDecorator | PropertyDecorator | ClassDecorator { - return (targetOrPrototype, propertyKey, _descriptor) => { +): MethodDecorator | PropertyDecorator | ClassDecorator | ParameterDecorator { + return ( + targetOrPrototype: Object, + propertyKey: string | symbol | undefined, + parameterIndexOrDescriptor: number | TypedPropertyDescriptor, + ) => { const directive = { nameOrDefinition, args: {} }; if (typeof propertyKey === "symbol") { throw new SymbolKeysNotSupportedError(); } if (propertyKey) { - getMetadataStorage().collectDirectiveFieldMetadata({ - target: targetOrPrototype.constructor, - fieldName: propertyKey, - directive, - }); + if (typeof parameterIndexOrDescriptor === "number") { + getMetadataStorage().collectDirectiveArgumentMetadata({ + target: targetOrPrototype.constructor, + fieldName: propertyKey, + parameterIndex: parameterIndexOrDescriptor, + directive, + }); + } else { + getMetadataStorage().collectDirectiveFieldMetadata({ + target: targetOrPrototype.constructor, + fieldName: propertyKey, + directive, + }); + } } else { getMetadataStorage().collectDirectiveClassMetadata({ target: targetOrPrototype as Function, diff --git a/src/decorators/Extensions.ts b/src/decorators/Extensions.ts index 276f300df..a005a1503 100644 --- a/src/decorators/Extensions.ts +++ b/src/decorators/Extensions.ts @@ -1,13 +1,13 @@ -import { MethodAndPropDecorator } from "./types"; -import { SymbolKeysNotSupportedError } from "../errors"; -import { getMetadataStorage } from "../metadata/getMetadataStorage"; -import { ExtensionsMetadata } from "../metadata/definitions"; +import { SymbolKeysNotSupportedError } from "@/errors"; +import { type ExtensionsMetadata } from "@/metadata/definitions"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { type MethodAndPropDecorator } from "./types"; export function Extensions(extensions: ExtensionsMetadata): MethodAndPropDecorator & ClassDecorator; export function Extensions( extensions: ExtensionsMetadata, ): MethodDecorator | PropertyDecorator | ClassDecorator { - return (targetOrPrototype, propertyKey, descriptor) => { + return (targetOrPrototype, propertyKey, _descriptor) => { if (typeof propertyKey === "symbol") { throw new SymbolKeysNotSupportedError(); } diff --git a/src/decorators/Field.ts b/src/decorators/Field.ts index 77c17854c..e75fd4d01 100644 --- a/src/decorators/Field.ts +++ b/src/decorators/Field.ts @@ -1,8 +1,8 @@ -import { getMetadataStorage } from "../metadata/getMetadataStorage"; -import { ReturnTypeFunc, AdvancedOptions, MethodAndPropDecorator } from "./types"; -import { findType } from "../helpers/findType"; -import { getTypeDecoratorParams } from "../helpers/decorators"; -import { SymbolKeysNotSupportedError } from "../errors"; +import { SymbolKeysNotSupportedError } from "@/errors"; +import { getTypeDecoratorParams } from "@/helpers/decorators"; +import { findType } from "@/helpers/findType"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { type AdvancedOptions, type MethodAndPropDecorator, type ReturnTypeFunc } from "./types"; export type FieldOptions = AdvancedOptions & { /** Set to `true` to disable auth and all middlewares stack for this field resolver */ diff --git a/src/decorators/FieldResolver.ts b/src/decorators/FieldResolver.ts index 1fc6820d1..b0332ca76 100644 --- a/src/decorators/FieldResolver.ts +++ b/src/decorators/FieldResolver.ts @@ -1,8 +1,13 @@ -import { getMetadataStorage } from "../metadata/getMetadataStorage"; -import { ReturnTypeFunc, AdvancedOptions, TypeValueThunk, TypeOptions } from "./types"; -import { SymbolKeysNotSupportedError } from "../errors"; -import { getTypeDecoratorParams } from "../helpers/decorators"; -import { findType } from "../helpers/findType"; +import { SymbolKeysNotSupportedError } from "@/errors"; +import { getTypeDecoratorParams } from "@/helpers/decorators"; +import { findType } from "@/helpers/findType"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { + type AdvancedOptions, + type ReturnTypeFunc, + type TypeOptions, + type TypeValueThunk, +} from "./types"; export function FieldResolver(): MethodDecorator; export function FieldResolver(options: AdvancedOptions): MethodDecorator; @@ -39,7 +44,7 @@ export function FieldResolver( typeOptions = typeInfo.typeOptions; getType = typeInfo.getType; } catch { - // tslint:disable-next-line:no-empty + /* empty */ } getMetadataStorage().collectFieldResolverMetadata({ diff --git a/src/decorators/Info.ts b/src/decorators/Info.ts index fb5f37081..79b4e5945 100644 --- a/src/decorators/Info.ts +++ b/src/decorators/Info.ts @@ -1,5 +1,6 @@ -import { getMetadataStorage } from "../metadata/getMetadataStorage"; -import { SymbolKeysNotSupportedError } from "../errors"; +import { SymbolKeysNotSupportedError } from "@/errors"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { type ParameterDecorator } from "@/typings"; export function Info(): ParameterDecorator { return (prototype, propertyKey, parameterIndex) => { diff --git a/src/decorators/InputType.ts b/src/decorators/InputType.ts index 5b54b28a6..d90caf8f1 100644 --- a/src/decorators/InputType.ts +++ b/src/decorators/InputType.ts @@ -1,8 +1,8 @@ -import { getMetadataStorage } from "../metadata/getMetadataStorage"; -import { getNameDecoratorParams } from "../helpers/decorators"; -import { DescriptionOptions, AbstractClassOptions } from "./types"; +import { getNameDecoratorParams } from "@/helpers/decorators"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { type DescriptionOptions } from "./types"; -export type InputTypeOptions = DescriptionOptions & AbstractClassOptions; +export type InputTypeOptions = DescriptionOptions; export function InputType(): ClassDecorator; export function InputType(options: InputTypeOptions): ClassDecorator; @@ -17,7 +17,6 @@ export function InputType( name: name || target.name, target, description: options.description, - isAbstract: options.isAbstract, }); }; } diff --git a/src/decorators/InterfaceType.ts b/src/decorators/InterfaceType.ts index 006b05f84..b95fb3f7e 100644 --- a/src/decorators/InterfaceType.ts +++ b/src/decorators/InterfaceType.ts @@ -1,14 +1,12 @@ -import { getMetadataStorage } from "../metadata/getMetadataStorage"; -import { getNameDecoratorParams } from "../helpers/decorators"; +import { getNameDecoratorParams } from "@/helpers/decorators"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; import { - DescriptionOptions, - AbstractClassOptions, - ResolveTypeOptions, - ImplementsClassOptions, + type DescriptionOptions, + type ImplementsClassOptions, + type ResolveTypeOptions, } from "./types"; export type InterfaceTypeOptions = DescriptionOptions & - AbstractClassOptions & ResolveTypeOptions & ImplementsClassOptions & { /** diff --git a/src/decorators/Mutation.ts b/src/decorators/Mutation.ts index e4a98f6ba..a1ba13243 100644 --- a/src/decorators/Mutation.ts +++ b/src/decorators/Mutation.ts @@ -1,7 +1,7 @@ -import { ReturnTypeFunc, AdvancedOptions } from "./types"; -import { getMetadataStorage } from "../metadata/getMetadataStorage"; -import { getResolverMetadata } from "../helpers/resolver-metadata"; -import { getTypeDecoratorParams } from "../helpers/decorators"; +import { getTypeDecoratorParams } from "@/helpers/decorators"; +import { getResolverMetadata } from "@/helpers/resolver-metadata"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { type AdvancedOptions, type ReturnTypeFunc } from "./types"; export function Mutation(): MethodDecorator; export function Mutation(options: AdvancedOptions): MethodDecorator; diff --git a/src/decorators/ObjectType.ts b/src/decorators/ObjectType.ts index 68cfb5d81..0d7587cfe 100644 --- a/src/decorators/ObjectType.ts +++ b/src/decorators/ObjectType.ts @@ -1,9 +1,8 @@ -import { getMetadataStorage } from "../metadata/getMetadataStorage"; -import { getNameDecoratorParams } from "../helpers/decorators"; -import { DescriptionOptions, AbstractClassOptions, ImplementsClassOptions } from "./types"; +import { getNameDecoratorParams } from "@/helpers/decorators"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { type DescriptionOptions, type ImplementsClassOptions } from "./types"; export type ObjectTypeOptions = DescriptionOptions & - AbstractClassOptions & ImplementsClassOptions & { /** Set to `true` to disable auth and all middlewares stack for all this Object Type fields resolvers */ simpleResolvers?: boolean; @@ -25,7 +24,6 @@ export function ObjectType( target, description: options.description, interfaceClasses, - isAbstract: options.isAbstract, simpleResolvers: options.simpleResolvers, }); }; diff --git a/src/decorators/PubSub.ts b/src/decorators/PubSub.ts deleted file mode 100644 index 94d69577f..000000000 --- a/src/decorators/PubSub.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { getMetadataStorage } from "../metadata/getMetadataStorage"; -import { SymbolKeysNotSupportedError } from "../errors"; - -export function PubSub(triggerKey?: string): ParameterDecorator { - return (prototype, propertyKey, parameterIndex) => { - if (typeof propertyKey === "symbol") { - throw new SymbolKeysNotSupportedError(); - } - - getMetadataStorage().collectHandlerParamMetadata({ - kind: "pubSub", - target: prototype.constructor, - methodName: propertyKey, - index: parameterIndex, - triggerKey, - }); - }; -} diff --git a/src/decorators/Query.ts b/src/decorators/Query.ts index 392cd81f4..0291c2c57 100644 --- a/src/decorators/Query.ts +++ b/src/decorators/Query.ts @@ -1,7 +1,7 @@ -import { ReturnTypeFunc, AdvancedOptions } from "./types"; -import { getMetadataStorage } from "../metadata/getMetadataStorage"; -import { getResolverMetadata } from "../helpers/resolver-metadata"; -import { getTypeDecoratorParams } from "../helpers/decorators"; +import { getTypeDecoratorParams } from "@/helpers/decorators"; +import { getResolverMetadata } from "@/helpers/resolver-metadata"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { type AdvancedOptions, type ReturnTypeFunc } from "./types"; export function Query(): MethodDecorator; export function Query(options: AdvancedOptions): MethodDecorator; diff --git a/src/decorators/Resolver.ts b/src/decorators/Resolver.ts index cf80e78c4..57974ec1e 100644 --- a/src/decorators/Resolver.ts +++ b/src/decorators/Resolver.ts @@ -1,28 +1,13 @@ -import { getMetadataStorage } from "../metadata/getMetadataStorage"; -import { ClassTypeResolver, AbstractClassOptions } from "./types"; -import { ClassType } from "../interfaces"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { type ClassType } from "@/typings"; +import { type ClassTypeResolver } from "./types"; export function Resolver(): ClassDecorator; -export function Resolver(options: AbstractClassOptions): ClassDecorator; -export function Resolver( - typeFunc: ClassTypeResolver, - options?: AbstractClassOptions, -): ClassDecorator; -export function Resolver(objectType: ClassType, options?: AbstractClassOptions): ClassDecorator; -export function Resolver( - objectTypeOrTypeFuncOrMaybeOptions?: Function | AbstractClassOptions, - maybeOptions?: AbstractClassOptions, -): ClassDecorator { - const objectTypeOrTypeFunc: Function | undefined = - typeof objectTypeOrTypeFuncOrMaybeOptions === "function" - ? objectTypeOrTypeFuncOrMaybeOptions - : undefined; - const options: AbstractClassOptions = - (typeof objectTypeOrTypeFuncOrMaybeOptions === "function" - ? maybeOptions - : objectTypeOrTypeFuncOrMaybeOptions) || {}; - +export function Resolver(typeFunc: ClassTypeResolver): ClassDecorator; +export function Resolver(objectType: ClassType): ClassDecorator; +export function Resolver(objectTypeOrTypeFunc?: Function): ClassDecorator { return target => { + // eslint-disable-next-line no-nested-ternary const getObjectType = objectTypeOrTypeFunc ? objectTypeOrTypeFunc.prototype ? () => objectTypeOrTypeFunc as ClassType @@ -35,7 +20,6 @@ export function Resolver( getMetadataStorage().collectResolverClassMetadata({ target, getObjectType, - isAbstract: options.isAbstract || false, }); }; } diff --git a/src/decorators/Root.ts b/src/decorators/Root.ts index bc218c812..9379e18f4 100644 --- a/src/decorators/Root.ts +++ b/src/decorators/Root.ts @@ -1,7 +1,8 @@ -import { getMetadataStorage } from "../metadata/getMetadataStorage"; -import { findType } from "../helpers/findType"; -import { TypeValueThunk } from "./types"; -import { SymbolKeysNotSupportedError } from "../errors"; +import { SymbolKeysNotSupportedError } from "@/errors"; +import { findType } from "@/helpers/findType"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { type ParameterDecorator } from "@/typings"; +import { type TypeValueThunk } from "./types"; export function Root(propertyName?: string): ParameterDecorator { return (prototype, propertyKey, parameterIndex) => { @@ -19,7 +20,7 @@ export function Root(propertyName?: string): ParameterDecorator { }); getType = typeInfo.getType; } catch { - // tslint:disable-next-line:no-empty + /* empty */ } getMetadataStorage().collectHandlerParamMetadata({ diff --git a/src/decorators/Subscription.ts b/src/decorators/Subscription.ts index cb1bcd4a6..bceb9a880 100644 --- a/src/decorators/Subscription.ts +++ b/src/decorators/Subscription.ts @@ -1,24 +1,25 @@ -import { ResolverFn } from "graphql-subscriptions"; - +import { MissingSubscriptionTopicsError } from "@/errors"; +import { getTypeDecoratorParams } from "@/helpers/decorators"; +import { getResolverMetadata } from "@/helpers/resolver-metadata"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { type MergeExclusive } from "@/typings"; import { - ReturnTypeFunc, - AdvancedOptions, - SubscriptionFilterFunc, - SubscriptionTopicFunc, + type AdvancedOptions, + type ReturnTypeFunc, + type SubscriptionFilterFunc, + type SubscriptionSubscribeFunc, + type SubscriptionTopicIdFunc, + type SubscriptionTopicsFunc, } from "./types"; -import { getMetadataStorage } from "../metadata/getMetadataStorage"; -import { getResolverMetadata } from "../helpers/resolver-metadata"; -import { getTypeDecoratorParams } from "../helpers/decorators"; -import { MissingSubscriptionTopicsError } from "../errors"; -import { MergeExclusive } from "../utils/types"; interface PubSubOptions { - topics: string | string[] | SubscriptionTopicFunc; + topics: string | string[] | SubscriptionTopicsFunc; + topicId?: SubscriptionTopicIdFunc | undefined; filter?: SubscriptionFilterFunc; } interface SubscribeOptions { - subscribe: ResolverFn; + subscribe: SubscriptionSubscribeFunc; } export type SubscriptionOptions = AdvancedOptions & MergeExclusive; @@ -42,6 +43,7 @@ export function Subscription( getMetadataStorage().collectSubscriptionHandlerMetadata({ ...metadata, topics: options.topics, + topicId: options.topicId, filter: options.filter, subscribe: options.subscribe, }); diff --git a/src/decorators/UseMiddleware.ts b/src/decorators/UseMiddleware.ts index ba52449c5..6f60f5a50 100644 --- a/src/decorators/UseMiddleware.ts +++ b/src/decorators/UseMiddleware.ts @@ -1,8 +1,8 @@ -import { SymbolKeysNotSupportedError } from "../errors"; -import { Middleware } from "../interfaces/Middleware"; -import { getMetadataStorage } from "../metadata/getMetadataStorage"; -import { getArrayFromOverloadedRest } from "../helpers/decorators"; -import { MethodAndPropDecorator } from "./types"; +import { SymbolKeysNotSupportedError } from "@/errors"; +import { getArrayFromOverloadedRest } from "@/helpers/decorators"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { type Middleware } from "@/typings/middleware"; +import { type MethodAndPropDecorator } from "./types"; export function UseMiddleware(middlewares: Array>): MethodAndPropDecorator; export function UseMiddleware(...middlewares: Array>): MethodAndPropDecorator; @@ -11,7 +11,7 @@ export function UseMiddleware( ): MethodDecorator | PropertyDecorator { const middlewares = getArrayFromOverloadedRest(middlewaresOrMiddlewareArray); - return (prototype, propertyKey, descriptor) => { + return (prototype, propertyKey, _descriptor) => { if (typeof propertyKey === "symbol") { throw new SymbolKeysNotSupportedError(); } diff --git a/src/decorators/createMethodDecorator.ts b/src/decorators/createMethodDecorator.ts index a81b0583d..6b1e3c9b8 100644 --- a/src/decorators/createMethodDecorator.ts +++ b/src/decorators/createMethodDecorator.ts @@ -1,7 +1,7 @@ +import { type MiddlewareFn } from "@/typings/middleware"; import { UseMiddleware } from "./UseMiddleware"; -import { MiddlewareFn } from "../interfaces/Middleware"; -export function createMethodDecorator( +export function createMethodDecorator( resolver: MiddlewareFn, ): MethodDecorator { return UseMiddleware(resolver); diff --git a/src/decorators/createParamDecorator.ts b/src/decorators/createParamDecorator.ts index 9f3a288b2..b3dbac283 100644 --- a/src/decorators/createParamDecorator.ts +++ b/src/decorators/createParamDecorator.ts @@ -1,8 +1,8 @@ -import { ResolverData } from "../interfaces"; -import { getMetadataStorage } from "../metadata/getMetadataStorage"; -import { SymbolKeysNotSupportedError } from "../errors"; +import { SymbolKeysNotSupportedError } from "@/errors"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { type ParameterDecorator, type ResolverData } from "@/typings"; -export function createParamDecorator( +export function createParamDecorator( resolver: (resolverData: ResolverData) => any, ): ParameterDecorator { return (prototype, propertyKey, parameterIndex) => { diff --git a/src/decorators/enums.ts b/src/decorators/enums.ts index 31c79529d..e798f8402 100644 --- a/src/decorators/enums.ts +++ b/src/decorators/enums.ts @@ -1,5 +1,5 @@ -import { EnumConfig } from "./types"; -import { getMetadataStorage } from "../metadata/getMetadataStorage"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { type EnumConfig } from "./types"; export function registerEnumType( enumObj: TEnum, diff --git a/src/decorators/index.ts b/src/decorators/index.ts index 720d8f11c..6c401373f 100644 --- a/src/decorators/index.ts +++ b/src/decorators/index.ts @@ -1,4 +1,5 @@ -export { Arg, ArgOptions } from "./Arg"; +export type { ArgOptions } from "./Arg"; +export { Arg } from "./Arg"; export { Args } from "./Args"; export { ArgsType } from "./ArgsType"; export { Authorized } from "./Authorized"; @@ -8,17 +9,21 @@ export { Ctx } from "./Ctx"; export { Directive } from "./Directive"; export { Extensions } from "./Extensions"; export { registerEnumType } from "./enums"; -export { Field, FieldOptions } from "./Field"; +export type { FieldOptions } from "./Field"; +export { Field } from "./Field"; export { FieldResolver } from "./FieldResolver"; export { Info } from "./Info"; -export { InputType, InputTypeOptions } from "./InputType"; -export { InterfaceType, InterfaceTypeOptions } from "./InterfaceType"; +export type { InputTypeOptions } from "./InputType"; +export { InputType } from "./InputType"; +export type { InterfaceTypeOptions } from "./InterfaceType"; +export { InterfaceType } from "./InterfaceType"; export { Mutation } from "./Mutation"; -export { ObjectType, ObjectTypeOptions } from "./ObjectType"; -export { PubSub } from "./PubSub"; +export type { ObjectTypeOptions } from "./ObjectType"; +export { ObjectType } from "./ObjectType"; export { Query } from "./Query"; export { Resolver } from "./Resolver"; export { Root } from "./Root"; -export { Subscription, SubscriptionOptions } from "./Subscription"; +export type { SubscriptionOptions } from "./Subscription"; +export { Subscription } from "./Subscription"; export { createUnionType } from "./unions"; export { UseMiddleware } from "./UseMiddleware"; diff --git a/src/decorators/types.ts b/src/decorators/types.ts index b25812aa1..8c805d25e 100644 --- a/src/decorators/types.ts +++ b/src/decorators/types.ts @@ -1,15 +1,16 @@ -import { GraphQLScalarType } from "graphql"; - +import { type GraphQLScalarType } from "graphql"; +import { type ValidateSettings } from "@/schema/build-context"; import { - ResolverFilterData, - ClassType, - ResolverTopicData, - Complexity, - TypeResolver, -} from "../interfaces"; -import { ValidateSettings } from "../schema/build-context"; + type ClassType, + type Complexity, + type MaybePromise, + type SubscribeResolverData, + type SubscriptionHandlerData, + type TypeResolver, + type ValidatorFn, +} from "@/typings"; -export interface RecursiveArray extends Array | TValue> {} +export type RecursiveArray = Array | TValue>; export type TypeValue = ClassType | GraphQLScalarType | Function | object | symbol; export type ReturnTypeFuncValue = TypeValue | RecursiveArray; @@ -20,13 +21,19 @@ export type ClassTypeResolver = (of?: void) => ClassType | Function; export type ReturnTypeFunc = (returns?: void) => ReturnTypeFuncValue; export type SubscriptionFilterFunc = ( - resolverFilterData: ResolverFilterData, + handlerData: SubscriptionHandlerData, ) => boolean | Promise; -export type SubscriptionTopicFunc = ( - resolverTopicData: ResolverTopicData, +export type SubscriptionTopicsFunc = ( + resolverData: SubscribeResolverData, ) => string | string[]; +export type SubscriptionSubscribeFunc = ( + resolverData: SubscribeResolverData, +) => MaybePromise>; + +export type SubscriptionTopicIdFunc = (resolverData: SubscribeResolverData) => any; + export interface DecoratorTypeOptions { nullable?: boolean | NullableListOptions; defaultValue?: any; @@ -46,6 +53,7 @@ export interface DeprecationOptions { } export interface ValidateOptions { validate?: ValidateSettings; + validateFn?: ValidatorFn; } export interface ComplexityOptions { complexity?: Complexity; @@ -53,9 +61,6 @@ export interface ComplexityOptions { export interface SchemaNameOptions { name?: string; } -export interface AbstractClassOptions { - isAbstract?: boolean; -} export interface ImplementsClassOptions { implements?: Function | Function[]; } diff --git a/src/decorators/unions.ts b/src/decorators/unions.ts index e31e37552..a879fbe22 100644 --- a/src/decorators/unions.ts +++ b/src/decorators/unions.ts @@ -1,14 +1,13 @@ -import { ClassType } from "../interfaces"; -import { getMetadataStorage } from "../metadata/getMetadataStorage"; -import { UnionFromClasses } from "../helpers/utils"; -import { ResolveTypeOptions } from "./types"; +import { type UnionFromClasses } from "@/helpers/utils"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { type ClassType } from "@/typings"; +import { type ResolveTypeOptions } from "./types"; -export interface UnionTypeConfig - extends ResolveTypeOptions> { +export type UnionTypeConfig = { name: string; description?: string; types: () => TClassTypes; -} +} & ResolveTypeOptions>; export function createUnionType( config: UnionTypeConfig, diff --git a/src/errors/ArgumentValidationError.ts b/src/errors/ArgumentValidationError.ts deleted file mode 100644 index 5e4dda17f..000000000 --- a/src/errors/ArgumentValidationError.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { ValidationError } from "class-validator"; - -export class ArgumentValidationError extends Error { - constructor(public validationErrors: ValidationError[]) { - super("Argument Validation Error"); - - Object.setPrototypeOf(this, new.target.prototype); - } -} diff --git a/src/errors/ConflictingDefaultValuesError.ts b/src/errors/ConflictingDefaultValuesError.ts index 3d4459843..514f3316c 100644 --- a/src/errors/ConflictingDefaultValuesError.ts +++ b/src/errors/ConflictingDefaultValuesError.ts @@ -2,8 +2,8 @@ export class ConflictingDefaultValuesError extends Error { constructor( typeName: string, fieldName: string, - defaultValueFromDecorator: any, - defaultValueFromInitializer: any, + defaultValueFromDecorator: unknown, + defaultValueFromInitializer: unknown, ) { super( `The '${fieldName}' field of '${typeName}' has conflicting default values. ` + diff --git a/src/errors/ForbiddenError.ts b/src/errors/ForbiddenError.ts deleted file mode 100644 index 20ae1bdeb..000000000 --- a/src/errors/ForbiddenError.ts +++ /dev/null @@ -1,7 +0,0 @@ -export class ForbiddenError extends Error { - constructor() { - super("Access denied! You don't have permission for this action!"); - - Object.setPrototypeOf(this, new.target.prototype); - } -} diff --git a/src/errors/GeneratingSchemaError.ts b/src/errors/GeneratingSchemaError.ts index 713d98df3..7555997d6 100644 --- a/src/errors/GeneratingSchemaError.ts +++ b/src/errors/GeneratingSchemaError.ts @@ -1,9 +1,9 @@ -import { GraphQLError } from "graphql"; +import { type GraphQLError } from "graphql"; export class GeneratingSchemaError extends Error { - details: ReadonlyArray; + details: readonly GraphQLError[]; - constructor(details: ReadonlyArray) { + constructor(details: readonly GraphQLError[]) { let errorMessage = "Some errors occurred while generating GraphQL schema:\n"; errorMessage += details.map(it => ` ${it.message}\n`); errorMessage += "Please check the `details` property of the error to get more detailed info."; diff --git a/src/errors/InterfaceResolveTypeError.ts b/src/errors/InterfaceResolveTypeError.ts index 48f404e81..4ff55fc54 100644 --- a/src/errors/InterfaceResolveTypeError.ts +++ b/src/errors/InterfaceResolveTypeError.ts @@ -1,4 +1,4 @@ -import { ClassMetadata } from "../metadata/definitions"; +import { type ClassMetadata } from "@/metadata/definitions"; export class InterfaceResolveTypeError extends Error { constructor(interfaceMetadata: ClassMetadata) { diff --git a/src/errors/MissingPubSubError.ts b/src/errors/MissingPubSubError.ts new file mode 100644 index 000000000..54934d3e1 --- /dev/null +++ b/src/errors/MissingPubSubError.ts @@ -0,0 +1,10 @@ +export class MissingPubSubError extends Error { + constructor() { + super( + "Looks like you've forgot to provide `pubSub` option in `buildSchema()`. " + + "Subscriptions can't work without a proper PubSub system.", + ); + + Object.setPrototypeOf(this, new.target.prototype); + } +} diff --git a/src/errors/UnauthorizedError.ts b/src/errors/UnauthorizedError.ts deleted file mode 100644 index 527fb5acb..000000000 --- a/src/errors/UnauthorizedError.ts +++ /dev/null @@ -1,7 +0,0 @@ -export class UnauthorizedError extends Error { - constructor() { - super("Access denied! You need to be authorized to perform this action!"); - - Object.setPrototypeOf(this, new.target.prototype); - } -} diff --git a/src/errors/UnionResolveTypeError.ts b/src/errors/UnionResolveTypeError.ts index 1daa228f3..47fe6cfc8 100644 --- a/src/errors/UnionResolveTypeError.ts +++ b/src/errors/UnionResolveTypeError.ts @@ -1,4 +1,4 @@ -import { UnionMetadata } from "../metadata/definitions"; +import { type UnionMetadata } from "@/metadata/definitions"; export class UnionResolveTypeError extends Error { constructor(unionMetadata: UnionMetadata) { diff --git a/src/errors/UnmetGraphQLPeerDependencyError.ts b/src/errors/UnmetGraphQLPeerDependencyError.ts index 53f140786..b2b874456 100644 --- a/src/errors/UnmetGraphQLPeerDependencyError.ts +++ b/src/errors/UnmetGraphQLPeerDependencyError.ts @@ -1,14 +1,9 @@ -import { - getPeerDependencyGraphQLRequirement, - getInstalledGraphQLVersion, -} from "../utils/graphql-version"; - export class UnmetGraphQLPeerDependencyError extends Error { - constructor() { + constructor(graphQLVersion: string, graphQLPeerDependencyVersion: string) { super( - `Looks like you use an incorrect version of the 'graphql' package: "${getInstalledGraphQLVersion()}". ` + + `Looks like you use an incorrect version of the 'graphql' package: "${graphQLVersion}". ` + `Please ensure that you have installed a version ` + - `that meets TypeGraphQL's requirement: "${getPeerDependencyGraphQLRequirement()}".`, + `that meets TypeGraphQL's requirement: "${graphQLPeerDependencyVersion}".`, ); Object.setPrototypeOf(this, new.target.prototype); diff --git a/src/errors/WrongNullableListOptionError.ts b/src/errors/WrongNullableListOptionError.ts index 2544bcbb1..5d1c07722 100644 --- a/src/errors/WrongNullableListOptionError.ts +++ b/src/errors/WrongNullableListOptionError.ts @@ -1,4 +1,4 @@ -import { NullableListOptions } from "../decorators/types"; +import { type NullableListOptions } from "@/decorators/types"; export class WrongNullableListOptionError extends Error { constructor( diff --git a/src/errors/graphql/ArgumentValidationError.ts b/src/errors/graphql/ArgumentValidationError.ts new file mode 100644 index 000000000..a38d5d546 --- /dev/null +++ b/src/errors/graphql/ArgumentValidationError.ts @@ -0,0 +1,23 @@ +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore `class-validator` might not be installed by user +import { type ValidationError } from "class-validator"; +import { GraphQLError } from "graphql"; + +export class ArgumentValidationError extends GraphQLError { + override readonly extensions!: { + code: "BAD_USER_INPUT"; + validationErrors: ValidationError[]; + [attributeName: string]: unknown; // GraphQLErrorExtensions + }; + + constructor(validationErrors: ValidationError[]) { + super("Argument Validation Error", { + extensions: { + code: "BAD_USER_INPUT", + validationErrors, + }, + }); + + Object.setPrototypeOf(this, new.target.prototype); + } +} diff --git a/src/errors/graphql/AuthenticationError.ts b/src/errors/graphql/AuthenticationError.ts new file mode 100644 index 000000000..0174d1215 --- /dev/null +++ b/src/errors/graphql/AuthenticationError.ts @@ -0,0 +1,18 @@ +import { GraphQLError } from "graphql"; + +export class AuthenticationError extends GraphQLError { + override readonly extensions!: { + code: "UNAUTHENTICATED"; + [attributeName: string]: unknown; // GraphQLErrorExtensions + }; + + constructor(message = "Access denied! You need to be authenticated to perform this action!") { + super(message, { + extensions: { + code: "UNAUTHENTICATED", + }, + }); + + Object.setPrototypeOf(this, new.target.prototype); + } +} diff --git a/src/errors/graphql/AuthorizationError.ts b/src/errors/graphql/AuthorizationError.ts new file mode 100644 index 000000000..c8ea14c96 --- /dev/null +++ b/src/errors/graphql/AuthorizationError.ts @@ -0,0 +1,18 @@ +import { GraphQLError } from "graphql"; + +export class AuthorizationError extends GraphQLError { + override readonly extensions!: { + code: "UNAUTHORIZED"; + [attributeName: string]: unknown; // GraphQLErrorExtensions + }; + + constructor(message = "Access denied! You don't have permission for this action!") { + super(message, { + extensions: { + code: "UNAUTHORIZED", + }, + }); + + Object.setPrototypeOf(this, new.target.prototype); + } +} diff --git a/src/errors/graphql/index.ts b/src/errors/graphql/index.ts new file mode 100644 index 000000000..69fed7f6a --- /dev/null +++ b/src/errors/graphql/index.ts @@ -0,0 +1,3 @@ +export * from "./AuthenticationError"; +export * from "./AuthorizationError"; +export * from "./ArgumentValidationError"; diff --git a/src/errors/index.ts b/src/errors/index.ts index 6aa10f91f..d94d1dfb1 100644 --- a/src/errors/index.ts +++ b/src/errors/index.ts @@ -1,15 +1,14 @@ -export * from "./ArgumentValidationError"; +export * from "./graphql"; export * from "./CannotDetermineGraphQLTypeError"; -export * from "./ForbiddenError"; export * from "./GeneratingSchemaError"; export * from "./ConflictingDefaultValuesError"; export * from "./InterfaceResolveTypeError"; export * from "./InvalidDirectiveError"; +export * from "./MissingPubSubError"; export * from "./MissingSubscriptionTopicsError"; export * from "./NoExplicitTypeError"; export * from "./ReflectMetadataMissingError"; export * from "./SymbolKeysNotSupportedError"; -export * from "./UnauthorizedError"; export * from "./UnionResolveTypeError"; export * from "./UnmetGraphQLPeerDependencyError"; export * from "./WrongNullableListOptionError"; diff --git a/src/helpers/auth-middleware.ts b/src/helpers/auth-middleware.ts index 32c306443..287d36ad5 100644 --- a/src/helpers/auth-middleware.ts +++ b/src/helpers/auth-middleware.ts @@ -1,7 +1,7 @@ -import { MiddlewareFn } from "../interfaces/Middleware"; -import { AuthChecker, AuthCheckerFn, AuthMode } from "../interfaces"; -import { UnauthorizedError, ForbiddenError } from "../errors"; -import { IOCContainer } from "../utils/container"; +import { AuthenticationError, AuthorizationError } from "@/errors"; +import { type AuthChecker, type AuthCheckerFn, type AuthMode } from "@/typings"; +import { type MiddlewareFn } from "@/typings/middleware"; +import { type IOCContainer } from "@/utils/container"; export function AuthMiddleware( authChecker: AuthChecker, @@ -21,8 +21,9 @@ export function AuthMiddleware( if (!accessGranted) { if (authMode === "null") { return null; - } else if (authMode === "error") { - throw roles.length === 0 ? new UnauthorizedError() : new ForbiddenError(); + } + if (authMode === "error") { + throw roles.length === 0 ? new AuthenticationError() : new AuthorizationError(); } } return next(); diff --git a/src/helpers/decorators.ts b/src/helpers/decorators.ts index 092fd6f2a..2397fe187 100644 --- a/src/helpers/decorators.ts +++ b/src/helpers/decorators.ts @@ -1,4 +1,4 @@ -import { ReturnTypeFunc, DescriptionOptions } from "../decorators/types"; +import { type DescriptionOptions, type ReturnTypeFunc } from "@/decorators/types"; export interface TypeDecoratorParams { options: Partial; @@ -13,11 +13,10 @@ export function getTypeDecoratorParams( returnTypeFunc: returnTypeFuncOrOptions as ReturnTypeFunc, options: maybeOptions || {}, }; - } else { - return { - options: returnTypeFuncOrOptions || {}, - }; } + return { + options: returnTypeFuncOrOptions || {}, + }; } export function getNameDecoratorParams( @@ -29,11 +28,10 @@ export function getNameDecoratorParams( name: nameOrOptions, options: maybeOptions || ({} as T), }; - } else { - return { - options: nameOrOptions || ({} as T), - }; } + return { + options: nameOrOptions || ({} as T), + }; } export function getArrayFromOverloadedRest(overloadedArray: Array): T[] { diff --git a/src/helpers/filesystem.ts b/src/helpers/filesystem.ts index 4b88d13e8..bc2ce93b4 100644 --- a/src/helpers/filesystem.ts +++ b/src/helpers/filesystem.ts @@ -1,67 +1,27 @@ -import path from "path"; -import fs from "fs"; -import { promisify } from "util"; - -export const fsMkdir = promisify(fs.mkdir); -export const fsWriteFile = promisify(fs.writeFile); - -export function parsePath(targetPath: string) { - const directories: string[] = []; - const parsedPath = path.parse(path.resolve(targetPath)); - const splitPath = parsedPath.dir.split(path.sep); - if (parsedPath.root === "/") { - splitPath[0] = `/${splitPath[0]}`; - } - splitPath.reduce((previous: string, next: string) => { - const directory = path.join(previous, next); - directories.push(directory); - return path.join(directory); - }); - return directories; -} - -export async function mkdirRecursive(filePath: string) { - const directories = parsePath(filePath); - for (const directory of directories) { - try { - await fsMkdir(directory); - } catch (err) { - if (err.code !== "EEXIST") { - throw err; - } - } - } -} - -export function mkdirRecursiveSync(filePath: string) { - const directories = parsePath(filePath); - for (const directory of directories) { - if (!fs.existsSync(directory)) { - fs.mkdirSync(directory); - } - } -} +import fs from "node:fs"; +import asyncFs from "node:fs/promises"; +import path from "node:path"; export async function outputFile(filePath: string, fileContent: any) { try { - await fsWriteFile(filePath, fileContent); + await asyncFs.writeFile(filePath, fileContent); } catch (err) { - if (err.code !== "ENOENT") { + if ((err as NodeJS.ErrnoException).code !== "ENOENT") { throw err; } - await mkdirRecursive(filePath); - await fsWriteFile(filePath, fileContent); + await asyncFs.mkdir(path.dirname(filePath), { recursive: true }); + await asyncFs.writeFile(filePath, fileContent); } } export function outputFileSync(filePath: string, fileContent: any) { try { fs.writeFileSync(filePath, fileContent); - } catch (e) { - if (e.code !== "ENOENT") { - throw e; + } catch (err) { + if ((err as NodeJS.ErrnoException).code !== "ENOENT") { + throw err; } - mkdirRecursiveSync(filePath); + fs.mkdirSync(path.dirname(filePath), { recursive: true }); fs.writeFileSync(filePath, fileContent); } } diff --git a/src/helpers/findType.ts b/src/helpers/findType.ts index db1cb896c..eb23b6f03 100644 --- a/src/helpers/findType.ts +++ b/src/helpers/findType.ts @@ -1,12 +1,13 @@ import { - ReturnTypeFunc, - TypeOptions, - TypeValueThunk, - TypeValue, - RecursiveArray, -} from "../decorators/types"; + type RecursiveArray, + type ReturnTypeFunc, + type TypeOptions, + type TypeValue, + type TypeValueThunk, +} from "@/decorators/types"; +import { NoExplicitTypeError } from "@/errors"; +import { ensureReflectMetadataExists } from "@/metadata/utils"; import { bannedTypes } from "./returnTypes"; -import { NoExplicitTypeError } from "../errors"; export type MetadataKey = "design:type" | "design:returntype" | "design:paramtypes"; @@ -24,6 +25,17 @@ export interface GetTypeParams { returnTypeFunc?: ReturnTypeFunc; typeOptions?: TypeOptions; } + +function findTypeValueArrayDepth( + [typeValueOrArray]: RecursiveArray, + innerDepth = 1, +): { depth: number; returnType: TypeValue } { + if (!Array.isArray(typeValueOrArray)) { + return { depth: innerDepth, returnType: typeValueOrArray }; + } + return findTypeValueArrayDepth(typeValueOrArray, innerDepth + 1); +} + export function findType({ metadataKey, prototype, @@ -35,6 +47,7 @@ export function findType({ }: GetTypeParams): TypeInfo { const options: TypeOptions = { ...typeOptions }; let metadataDesignType: Function | undefined; + ensureReflectMetadataExists(); const reflectedType: Function[] | Function | undefined = Reflect.getMetadata( metadataKey, prototype, @@ -67,22 +80,12 @@ export function findType({ getType, typeOptions: options, }; - } else if (metadataDesignType) { + } + if (metadataDesignType) { return { getType: () => metadataDesignType!, typeOptions: options, }; - } else { - throw new Error("Ooops... this should never happen :)"); } -} - -function findTypeValueArrayDepth( - [typeValueOrArray]: RecursiveArray, - innerDepth = 1, -): { depth: number; returnType: TypeValue } { - if (!Array.isArray(typeValueOrArray)) { - return { depth: innerDepth, returnType: typeValueOrArray }; - } - return findTypeValueArrayDepth(typeValueOrArray, innerDepth + 1); + throw new Error("Ops... this should never happen :)"); } diff --git a/src/helpers/loadResolversFromGlob.ts b/src/helpers/loadResolversFromGlob.ts deleted file mode 100644 index 00fe703b2..000000000 --- a/src/helpers/loadResolversFromGlob.ts +++ /dev/null @@ -1,10 +0,0 @@ -import glob from "glob"; - -export function findFileNamesFromGlob(globString: string) { - return glob.sync(globString); -} - -export function loadResolversFromGlob(globString: string) { - const filePaths = findFileNamesFromGlob(globString); - const modules = filePaths.map(fileName => require(fileName)); -} diff --git a/src/helpers/params.ts b/src/helpers/params.ts index 16538f314..e2d739413 100644 --- a/src/helpers/params.ts +++ b/src/helpers/params.ts @@ -1,7 +1,7 @@ +import { type ReturnTypeFunc, type TypeOptions, type ValidateOptions } from "@/decorators/types"; +import { SymbolKeysNotSupportedError } from "@/errors"; +import { type CommonArgMetadata } from "@/metadata/definitions"; import { findType } from "./findType"; -import { ReturnTypeFunc, TypeOptions, ValidateOptions } from "../decorators/types"; -import { CommonArgMetadata } from "../metadata/definitions"; -import { SymbolKeysNotSupportedError } from "../errors"; export interface ParamInfo { prototype: Object; @@ -39,6 +39,7 @@ export function getParamInfo({ index: parameterIndex, getType, typeOptions, - validate: options.validate, + validateSettings: options.validate, + validateFn: options.validateFn, }; } diff --git a/src/helpers/resolver-metadata.ts b/src/helpers/resolver-metadata.ts index 2a311ca4f..b6ea3e148 100644 --- a/src/helpers/resolver-metadata.ts +++ b/src/helpers/resolver-metadata.ts @@ -1,7 +1,7 @@ -import { ResolverMetadata } from "../metadata/definitions"; -import { ReturnTypeFunc, AdvancedOptions } from "../decorators/types"; +import { type AdvancedOptions, type ReturnTypeFunc } from "@/decorators/types"; +import { SymbolKeysNotSupportedError } from "@/errors"; +import { type ResolverMetadata } from "@/metadata/definitions"; import { findType } from "./findType"; -import { SymbolKeysNotSupportedError } from "../errors"; export function getResolverMetadata( prototype: object, diff --git a/src/helpers/types.ts b/src/helpers/types.ts index 01ecaee3e..afe167a9a 100644 --- a/src/helpers/types.ts +++ b/src/helpers/types.ts @@ -1,18 +1,29 @@ import { - GraphQLScalarType, - GraphQLString, + GraphQLBoolean, GraphQLFloat, - GraphQLType, - GraphQLNonNull, GraphQLList, - GraphQLBoolean, + GraphQLNonNull, + GraphQLScalarType, + GraphQLString, + type GraphQLType, } from "graphql"; +import { type TypeOptions } from "@/decorators/types"; +import { WrongNullableListOptionError } from "@/errors"; +import { GraphQLISODateTime } from "@/scalars"; +import { BuildContext } from "@/schema/build-context"; -import { TypeOptions } from "../decorators/types"; -import { GraphQLTimestamp } from "../scalars/timestamp"; -import { GraphQLISODateTime } from "../scalars/isodate"; -import { BuildContext } from "../schema/build-context"; -import { WrongNullableListOptionError } from "../errors"; +function wrapTypeInNestedList( + targetType: GraphQLType, + depth: number, + nullable: boolean, +): GraphQLList { + const targetTypeNonNull = nullable ? targetType : new GraphQLNonNull(targetType); + + if (depth === 0) { + return targetType as GraphQLList; + } + return wrapTypeInNestedList(new GraphQLList(targetTypeNonNull), depth - 1, nullable); +} export function convertTypeIfScalar(type: any): GraphQLScalarType | undefined { if (type instanceof GraphQLScalarType) { @@ -31,7 +42,7 @@ export function convertTypeIfScalar(type: any): GraphQLScalarType | undefined { case Number: return GraphQLFloat; case Date: - return BuildContext.dateScalarMode === "isoDate" ? GraphQLISODateTime : GraphQLTimestamp; + return GraphQLISODateTime; default: return undefined; } @@ -99,23 +110,11 @@ export function convertToType(Target: any, data?: object): object | undefined { } export function getEnumValuesMap(enumObject: T) { - const enumKeys = Object.keys(enumObject).filter(key => isNaN(parseInt(key, 10))); + const enumKeys = Object.keys(enumObject).filter(key => Number.isNaN(parseInt(key, 10))); const enumMap = enumKeys.reduce((map, key) => { + // eslint-disable-next-line no-param-reassign map[key] = enumObject[key as keyof T]; return map; }, {}); return enumMap; } - -function wrapTypeInNestedList( - targetType: GraphQLType, - depth: number, - nullable: boolean, -): GraphQLList { - const targetTypeNonNull = nullable ? targetType : new GraphQLNonNull(targetType); - - if (depth === 0) { - return targetType as GraphQLList; - } - return wrapTypeInNestedList(new GraphQLList(targetTypeNonNull), depth - 1, nullable); -} diff --git a/src/helpers/utils.ts b/src/helpers/utils.ts index e8eda36e6..f47d13593 100644 --- a/src/helpers/utils.ts +++ b/src/helpers/utils.ts @@ -1,9 +1,6 @@ -export type ArrayElements> = TArray extends ReadonlyArray< - infer TElement -> - ? TElement - : never; +export type ArrayElements = + TArray extends ReadonlyArray ? TElement : never; -export type UnionFromClasses> = InstanceType< +export type UnionFromClasses = InstanceType< ArrayElements >; diff --git a/src/index.ts b/src/index.ts index eaf52cd76..9945117bf 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,8 +1,6 @@ export * from "./decorators"; export * from "./errors"; -export * from "./interfaces"; +export * from "./typings"; export * from "./metadata"; export * from "./scalars"; export * from "./utils"; - -export { PubSubEngine } from "graphql-subscriptions"; diff --git a/src/interfaces/AuthChecker.ts b/src/interfaces/AuthChecker.ts deleted file mode 100644 index 4ed40bb7f..000000000 --- a/src/interfaces/AuthChecker.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { ClassType } from "./ClassType"; -import { ResolverData } from "./ResolverData"; - -export type AuthCheckerFn = ( - resolverData: ResolverData, - roles: TRoleType[], -) => boolean | Promise; - -export type AuthCheckerInterface = { - check(resolverData: ResolverData, roles: TRoleType[]): boolean | Promise; -}; - -export type AuthChecker = - | AuthCheckerFn - | ClassType>; - -export type AuthMode = "error" | "null"; diff --git a/src/interfaces/ClassType.ts b/src/interfaces/ClassType.ts deleted file mode 100644 index 90141b923..000000000 --- a/src/interfaces/ClassType.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface ClassType { - new (...args: any[]): T; -} diff --git a/src/interfaces/Complexity.ts b/src/interfaces/Complexity.ts deleted file mode 100644 index 0b75ab746..000000000 --- a/src/interfaces/Complexity.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { ComplexityEstimator } from "graphql-query-complexity"; - -export type Complexity = ComplexityEstimator | number; diff --git a/src/interfaces/Middleware.ts b/src/interfaces/Middleware.ts deleted file mode 100644 index b71c67e4f..000000000 --- a/src/interfaces/Middleware.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { ResolverData } from "./ResolverData"; - -export type NextFn = () => Promise; - -export type MiddlewareFn = ( - action: ResolverData, - next: NextFn, -) => Promise; - -export interface MiddlewareInterface { - use: MiddlewareFn; -} -export interface MiddlewareClass { - new (...args: any[]): MiddlewareInterface; -} - -export type Middleware = MiddlewareFn | MiddlewareClass; diff --git a/src/interfaces/NonEmptyArray.ts b/src/interfaces/NonEmptyArray.ts deleted file mode 100644 index 167b974fd..000000000 --- a/src/interfaces/NonEmptyArray.ts +++ /dev/null @@ -1 +0,0 @@ -export type NonEmptyArray = readonly [TItem, ...TItem[]] | [TItem, ...TItem[]]; diff --git a/src/interfaces/Publisher.ts b/src/interfaces/Publisher.ts deleted file mode 100644 index 840d59f1e..000000000 --- a/src/interfaces/Publisher.ts +++ /dev/null @@ -1 +0,0 @@ -export type Publisher = (payload: T) => Promise; diff --git a/src/interfaces/ResolverData.ts b/src/interfaces/ResolverData.ts deleted file mode 100644 index de129699f..000000000 --- a/src/interfaces/ResolverData.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { GraphQLResolveInfo } from "graphql"; - -export interface ArgsDictionary { - [argName: string]: any; -} - -export interface ResolverData { - root: any; - args: ArgsDictionary; - context: ContextType; - info: GraphQLResolveInfo; -} diff --git a/src/interfaces/ResolverFilterData.ts b/src/interfaces/ResolverFilterData.ts deleted file mode 100644 index 194f28ace..000000000 --- a/src/interfaces/ResolverFilterData.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { GraphQLResolveInfo } from "graphql"; - -import { ArgsDictionary } from "./ResolverData"; - -export interface ResolverFilterData { - payload: TPayload; - args: TArgs; - context: TContext; - info: GraphQLResolveInfo; -} diff --git a/src/interfaces/ResolverTopicData.ts b/src/interfaces/ResolverTopicData.ts deleted file mode 100644 index c3c4794cb..000000000 --- a/src/interfaces/ResolverTopicData.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { ResolverFilterData } from "./ResolverFilterData"; -import { ArgsDictionary } from "./ResolverData"; - -export type ResolverTopicData< - TPayload = any, - TArgs = ArgsDictionary, - TContext = {} -> = ResolverFilterData; diff --git a/src/interfaces/ValidatorFn.ts b/src/interfaces/ValidatorFn.ts deleted file mode 100644 index 8ef677414..000000000 --- a/src/interfaces/ValidatorFn.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { TypeValue } from "../decorators/types"; - -export type ValidatorFn = ( - argValue: T | undefined, - argType: TypeValue, -) => void | Promise; diff --git a/src/interfaces/index.ts b/src/interfaces/index.ts deleted file mode 100644 index 7d506bb65..000000000 --- a/src/interfaces/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -export * from "./AuthChecker"; -export * from "./ClassType"; -export * from "./Complexity"; -export * from "./Maybe"; -export { MiddlewareFn, NextFn, MiddlewareInterface } from "./Middleware"; -export * from "./NonEmptyArray"; -export * from "./Publisher"; -export * from "./ResolverData"; -export * from "./ResolverFilterData"; -export * from "./ResolverInterface"; -export * from "./resolvers-map"; -export * from "./ResolverTopicData"; -export * from "./TypeResolver"; diff --git a/src/interfaces/resolvers-map.ts b/src/interfaces/resolvers-map.ts deleted file mode 100644 index 05ac5259d..000000000 --- a/src/interfaces/resolvers-map.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { - GraphQLScalarType, - GraphQLFieldResolver, - GraphQLTypeResolver, - GraphQLIsTypeOfFn, -} from "graphql"; - -export interface ResolversMap { - [key: string]: - | ResolverObject - | ResolverOptions - | GraphQLScalarType - | EnumResolver; -} - -export interface ResolverObject { - [key: string]: ResolverOptions | GraphQLFieldResolver; -} - -export interface EnumResolver { - [key: string]: string | number; -} - -export interface ResolverOptions { - fragment?: string; - resolve?: GraphQLFieldResolver; - subscribe?: GraphQLFieldResolver; - __resolveType?: GraphQLTypeResolver; - __isTypeOf?: GraphQLIsTypeOfFn; -} diff --git a/src/metadata/definitions/class-metadata.ts b/src/metadata/definitions/class-metadata.ts index 0155622df..9eeef649e 100644 --- a/src/metadata/definitions/class-metadata.ts +++ b/src/metadata/definitions/class-metadata.ts @@ -1,13 +1,12 @@ -import { FieldMetadata } from "./field-metadata"; -import { DirectiveMetadata } from "./directive-metadata"; -import { ExtensionsMetadata } from "./extensions-metadata"; +import { type DirectiveMetadata } from "./directive-metadata"; +import { type ExtensionsMetadata } from "./extensions-metadata"; +import { type FieldMetadata } from "./field-metadata"; export interface ClassMetadata { name: string; target: Function; fields?: FieldMetadata[]; description?: string; - isAbstract?: boolean; directives?: DirectiveMetadata[]; extensions?: ExtensionsMetadata; simpleResolvers?: boolean; diff --git a/src/metadata/definitions/directive-metadata.ts b/src/metadata/definitions/directive-metadata.ts index b5c46b169..698a9ac16 100644 --- a/src/metadata/definitions/directive-metadata.ts +++ b/src/metadata/definitions/directive-metadata.ts @@ -13,3 +13,10 @@ export interface DirectiveFieldMetadata { fieldName: string; directive: DirectiveMetadata; } + +export interface DirectiveArgumentMetadata { + target: Function; + fieldName: string; + parameterIndex: number; + directive: DirectiveMetadata; +} diff --git a/src/metadata/definitions/enum-metadata.ts b/src/metadata/definitions/enum-metadata.ts index d6fb6b73b..2fb295423 100644 --- a/src/metadata/definitions/enum-metadata.ts +++ b/src/metadata/definitions/enum-metadata.ts @@ -1,4 +1,4 @@ -import { EnumValuesConfig } from "../../decorators/types"; +import { type EnumValuesConfig } from "@/decorators/types"; export interface EnumMetadata { enumObj: object; diff --git a/src/metadata/definitions/field-metadata.ts b/src/metadata/definitions/field-metadata.ts index d5ce485c4..ec2eb0767 100644 --- a/src/metadata/definitions/field-metadata.ts +++ b/src/metadata/definitions/field-metadata.ts @@ -1,9 +1,9 @@ -import { ParamMetadata } from "./param-metadata"; -import { TypeValueThunk, TypeOptions } from "../../decorators/types"; -import { Middleware } from "../../interfaces/Middleware"; -import { Complexity } from "../../interfaces"; -import { DirectiveMetadata } from "./directive-metadata"; -import { ExtensionsMetadata } from "./extensions-metadata"; +import { type TypeOptions, type TypeValueThunk } from "@/decorators/types"; +import { type Complexity } from "@/typings"; +import { type Middleware } from "@/typings/middleware"; +import { type DirectiveMetadata } from "./directive-metadata"; +import { type ExtensionsMetadata } from "./extensions-metadata"; +import { type ParamMetadata } from "./param-metadata"; export interface FieldMetadata { target: Function; diff --git a/src/metadata/definitions/interface-class-metadata.ts b/src/metadata/definitions/interface-class-metadata.ts index abc8981e0..012f074e3 100644 --- a/src/metadata/definitions/interface-class-metadata.ts +++ b/src/metadata/definitions/interface-class-metadata.ts @@ -1,8 +1,8 @@ -import { ClassMetadata } from "./class-metadata"; -import { TypeResolver } from "../../interfaces"; +import { type TypeResolver } from "@/typings"; +import { type ClassMetadata } from "./class-metadata"; -export interface InterfaceClassMetadata extends ClassMetadata { +export type InterfaceClassMetadata = { resolveType?: TypeResolver; autoRegisteringDisabled: boolean; interfaceClasses: Function[] | undefined; -} +} & ClassMetadata; diff --git a/src/metadata/definitions/middleware-metadata.ts b/src/metadata/definitions/middleware-metadata.ts index 07bf7ba9b..400da77ed 100644 --- a/src/metadata/definitions/middleware-metadata.ts +++ b/src/metadata/definitions/middleware-metadata.ts @@ -1,4 +1,4 @@ -import { Middleware } from "../../interfaces/Middleware"; +import { type Middleware } from "@/typings/middleware"; export interface MiddlewareMetadata { target: Function; diff --git a/src/metadata/definitions/object-class-metadata.ts b/src/metadata/definitions/object-class-metadata.ts new file mode 100644 index 000000000..f977205d5 --- /dev/null +++ b/src/metadata/definitions/object-class-metadata.ts @@ -0,0 +1,5 @@ +import { type ClassMetadata } from "./class-metadata"; + +export type ObjectClassMetadata = { + interfaceClasses: Function[] | undefined; +} & ClassMetadata; diff --git a/src/metadata/definitions/object-class-metdata.ts b/src/metadata/definitions/object-class-metdata.ts deleted file mode 100644 index 7c227a5cc..000000000 --- a/src/metadata/definitions/object-class-metdata.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { ClassMetadata } from "./class-metadata"; - -export interface ObjectClassMetadata extends ClassMetadata { - interfaceClasses: Function[] | undefined; -} diff --git a/src/metadata/definitions/param-metadata.ts b/src/metadata/definitions/param-metadata.ts index ffa035422..16ee241a3 100644 --- a/src/metadata/definitions/param-metadata.ts +++ b/src/metadata/definitions/param-metadata.ts @@ -1,47 +1,56 @@ -import { TypeValueThunk, TypeOptions } from "../../decorators/types"; -import { ResolverData } from "../../interfaces"; -import { ValidateSettings } from "../../schema/build-context"; +import { type TypeOptions, type TypeValueThunk } from "@/decorators/types"; +import { type ValidateSettings } from "@/schema/build-context"; +import { type ResolverData, type ValidatorFn } from "@/typings"; export interface BasicParamMetadata { target: Function; methodName: string; index: number; } -export interface InfoParamMetadata extends BasicParamMetadata { + +export type InfoParamMetadata = { kind: "info"; -} -export interface PubSubParamMetadata extends BasicParamMetadata { +} & BasicParamMetadata; + +export type PubSubParamMetadata = { kind: "pubSub"; triggerKey?: string; -} -export interface ContextParamMetadata extends BasicParamMetadata { +} & BasicParamMetadata; + +export type ContextParamMetadata = { kind: "context"; propertyName: string | undefined; -} -export interface RootParamMetadata extends BasicParamMetadata { +} & BasicParamMetadata; + +export type RootParamMetadata = { kind: "root"; propertyName: string | undefined; getType: TypeValueThunk | undefined; -} -export interface CommonArgMetadata extends BasicParamMetadata { +} & BasicParamMetadata; + +export type CommonArgMetadata = { getType: TypeValueThunk; typeOptions: TypeOptions; - validate: ValidateSettings | undefined; -} -export interface ArgParamMetadata extends CommonArgMetadata { + validateSettings: ValidateSettings | undefined; + validateFn: ValidatorFn | undefined; +} & BasicParamMetadata; + +export type ArgParamMetadata = { kind: "arg"; name: string; description: string | undefined; deprecationReason: string | undefined; -} -export interface ArgsParamMetadata extends CommonArgMetadata { +} & CommonArgMetadata; + +export type ArgsParamMetadata = { kind: "args"; -} -export interface CustomParamMetadata extends BasicParamMetadata { +} & CommonArgMetadata; + +export type CustomParamMetadata = { kind: "custom"; resolver: (resolverData: ResolverData) => any; -} -// prettier-ignore +} & BasicParamMetadata; + export type ParamMetadata = | InfoParamMetadata | PubSubParamMetadata @@ -49,5 +58,4 @@ export type ParamMetadata = | RootParamMetadata | ArgParamMetadata | ArgsParamMetadata - | CustomParamMetadata -; + | CustomParamMetadata; diff --git a/src/metadata/definitions/resolver-metadata.ts b/src/metadata/definitions/resolver-metadata.ts index 913039be1..5f388b447 100644 --- a/src/metadata/definitions/resolver-metadata.ts +++ b/src/metadata/definitions/resolver-metadata.ts @@ -1,17 +1,17 @@ -import { ResolverFn } from "graphql-subscriptions"; - import { - TypeValueThunk, - TypeOptions, - ClassTypeResolver, - SubscriptionFilterFunc, - SubscriptionTopicFunc, -} from "../../decorators/types"; -import { ParamMetadata } from "./param-metadata"; -import { Middleware } from "../../interfaces/Middleware"; -import { Complexity } from "../../interfaces"; -import { DirectiveMetadata } from "./directive-metadata"; -import { ExtensionsMetadata } from "./extensions-metadata"; + type ClassTypeResolver, + type SubscriptionFilterFunc, + type SubscriptionSubscribeFunc, + type SubscriptionTopicIdFunc, + type SubscriptionTopicsFunc, + type TypeOptions, + type TypeValueThunk, +} from "@/decorators/types"; +import { type Complexity } from "@/typings"; +import { type Middleware } from "@/typings/middleware"; +import { type DirectiveMetadata } from "./directive-metadata"; +import { type ExtensionsMetadata } from "./extensions-metadata"; +import { type ParamMetadata } from "./param-metadata"; export interface BaseResolverMetadata { methodName: string; @@ -26,31 +26,31 @@ export interface BaseResolverMetadata { extensions?: ExtensionsMetadata; } -export interface ResolverMetadata extends BaseResolverMetadata { +export type ResolverMetadata = { getReturnType: TypeValueThunk; returnTypeOptions: TypeOptions; description?: string; deprecationReason?: string; -} +} & BaseResolverMetadata; -export interface FieldResolverMetadata extends BaseResolverMetadata { +export type FieldResolverMetadata = { kind: "internal" | "external"; description?: string; deprecationReason?: string; getType?: TypeValueThunk; typeOptions?: TypeOptions; getObjectType?: ClassTypeResolver; -} +} & BaseResolverMetadata; -export interface SubscriptionResolverMetadata extends ResolverMetadata { - topics: string | string[] | SubscriptionTopicFunc | undefined; +export type SubscriptionResolverMetadata = { + topics: string | string[] | SubscriptionTopicsFunc | undefined; + topicId: SubscriptionTopicIdFunc | undefined; filter: SubscriptionFilterFunc | undefined; - subscribe: ResolverFn | undefined; -} + subscribe: SubscriptionSubscribeFunc | undefined; +} & ResolverMetadata; export interface ResolverClassMetadata { target: Function; getObjectType: ClassTypeResolver; - isAbstract?: boolean; superResolver?: ResolverClassMetadata; } diff --git a/src/metadata/definitions/union-metadata.ts b/src/metadata/definitions/union-metadata.ts index 067077060..5ccc86ee1 100644 --- a/src/metadata/definitions/union-metadata.ts +++ b/src/metadata/definitions/union-metadata.ts @@ -1,4 +1,4 @@ -import { ClassType, TypeResolver } from "../../interfaces"; +import { type ClassType, type TypeResolver } from "@/typings"; export interface UnionMetadata { getClassTypes: () => ClassType[]; @@ -6,6 +6,6 @@ export interface UnionMetadata { description?: string; resolveType?: TypeResolver; } -export interface UnionMetadataWithSymbol extends UnionMetadata { +export type UnionMetadataWithSymbol = { symbol: symbol; -} +} & UnionMetadata; diff --git a/src/metadata/getMetadataStorage.ts b/src/metadata/getMetadataStorage.ts index 261934f20..25ff0b0e9 100644 --- a/src/metadata/getMetadataStorage.ts +++ b/src/metadata/getMetadataStorage.ts @@ -1,7 +1,14 @@ -import { MetadataStorage } from "../metadata/metadata-storage"; +import { MetadataStorage } from "./metadata-storage"; + +declare global { + // eslint-disable-next-line vars-on-top, no-var + var TypeGraphQLMetadataStorage: MetadataStorage; +} export function getMetadataStorage(): MetadataStorage { - return ( - global.TypeGraphQLMetadataStorage || (global.TypeGraphQLMetadataStorage = new MetadataStorage()) - ); + if (!global.TypeGraphQLMetadataStorage) { + global.TypeGraphQLMetadataStorage = new MetadataStorage(); + } + + return global.TypeGraphQLMetadataStorage; } diff --git a/src/metadata/metadata-storage.ts b/src/metadata/metadata-storage.ts index 0c7c8f1bd..82fe11f09 100644 --- a/src/metadata/metadata-storage.ts +++ b/src/metadata/metadata-storage.ts @@ -1,89 +1,119 @@ +/* eslint-disable no-param-reassign */ +import { NoExplicitTypeError } from "@/errors"; +import { type SchemaGeneratorOptions } from "@/schema/schema-generator"; +import { type ClassType } from "@/typings"; import { - ResolverMetadata, - ClassMetadata, - ExtensionsClassMetadata, - ExtensionsFieldMetadata, - FieldMetadata, - ParamMetadata, - FieldResolverMetadata, - AuthorizedMetadata, - BaseResolverMetadata, - EnumMetadata, - UnionMetadata, - UnionMetadataWithSymbol, - ResolverClassMetadata, - SubscriptionResolverMetadata, - MiddlewareMetadata, - ExtensionsMetadata, + type AuthorizedMetadata, + type BaseResolverMetadata, + type ClassMetadata, + type EnumMetadata, + type ExtensionsClassMetadata, + type ExtensionsFieldMetadata, + type ExtensionsMetadata, + type FieldMetadata, + type FieldResolverMetadata, + type MiddlewareMetadata, + type ParamMetadata, + type ResolverClassMetadata, + type ResolverMetadata, + type SubscriptionResolverMetadata, + type UnionMetadata, + type UnionMetadataWithSymbol, } from "./definitions"; -import { ClassType } from "../interfaces"; -import { NoExplicitTypeError } from "../errors"; import { - mapSuperResolverHandlers, + type DirectiveArgumentMetadata, + type DirectiveClassMetadata, + type DirectiveFieldMetadata, +} from "./definitions/directive-metadata"; +import { type InterfaceClassMetadata } from "./definitions/interface-class-metadata"; +import { type ObjectClassMetadata } from "./definitions/object-class-metadata"; +import { mapMiddlewareMetadataToArray, mapSuperFieldResolverHandlers, - ensureReflectMetadataExists, + mapSuperResolverHandlers, } from "./utils"; -import { ObjectClassMetadata } from "./definitions/object-class-metdata"; -import { InterfaceClassMetadata } from "./definitions/interface-class-metadata"; -import { DirectiveClassMetadata, DirectiveFieldMetadata } from "./definitions/directive-metadata"; -import { SchemaGeneratorOptions } from "../schema/schema-generator"; export class MetadataStorage { queries: ResolverMetadata[] = []; + mutations: ResolverMetadata[] = []; + subscriptions: SubscriptionResolverMetadata[] = []; + fieldResolvers: FieldResolverMetadata[] = []; + objectTypes: ObjectClassMetadata[] = []; + inputTypes: ClassMetadata[] = []; + argumentTypes: ClassMetadata[] = []; + interfaceTypes: InterfaceClassMetadata[] = []; + authorizedFields: AuthorizedMetadata[] = []; + enums: EnumMetadata[] = []; + unions: UnionMetadataWithSymbol[] = []; + middlewares: MiddlewareMetadata[] = []; + classDirectives: DirectiveClassMetadata[] = []; + fieldDirectives: DirectiveFieldMetadata[] = []; + + argumentDirectives: DirectiveArgumentMetadata[] = []; + classExtensions: ExtensionsClassMetadata[] = []; + fieldExtensions: ExtensionsFieldMetadata[] = []; + resolverClasses: ResolverClassMetadata[] = []; + fields: FieldMetadata[] = []; - params: ParamMetadata[] = []; - constructor() { - ensureReflectMetadataExists(); - } + params: ParamMetadata[] = []; collectQueryHandlerMetadata(definition: ResolverMetadata) { this.queries.push(definition); } + collectMutationHandlerMetadata(definition: ResolverMetadata) { this.mutations.push(definition); } + collectSubscriptionHandlerMetadata(definition: SubscriptionResolverMetadata) { this.subscriptions.push(definition); } + collectFieldResolverMetadata(definition: FieldResolverMetadata) { this.fieldResolvers.push(definition); } + collectObjectMetadata(definition: ObjectClassMetadata) { this.objectTypes.push(definition); } + collectInputMetadata(definition: ClassMetadata) { this.inputTypes.push(definition); } + collectArgsMetadata(definition: ClassMetadata) { this.argumentTypes.push(definition); } + collectInterfaceMetadata(definition: InterfaceClassMetadata) { this.interfaceTypes.push(definition); } + collectAuthorizedFieldMetadata(definition: AuthorizedMetadata) { this.authorizedFields.push(definition); } + collectEnumMetadata(definition: EnumMetadata) { this.enums.push(definition); } + collectUnionMetadata(definition: UnionMetadata) { const unionSymbol = Symbol(definition.name); this.unions.push({ @@ -92,6 +122,7 @@ export class MetadataStorage { }); return unionSymbol; } + collectMiddlewareMetadata(definition: MiddlewareMetadata) { this.middlewares.push(definition); } @@ -99,9 +130,11 @@ export class MetadataStorage { collectResolverClassMetadata(definition: ResolverClassMetadata) { this.resolverClasses.push(definition); } + collectClassFieldMetadata(definition: FieldMetadata) { this.fields.push(definition); } + collectHandlerParamMetadata(definition: ParamMetadata) { this.params.push(definition); } @@ -109,13 +142,19 @@ export class MetadataStorage { collectDirectiveClassMetadata(definition: DirectiveClassMetadata) { this.classDirectives.push(definition); } + collectDirectiveFieldMetadata(definition: DirectiveFieldMetadata) { this.fieldDirectives.push(definition); } + collectDirectiveArgumentMetadata(definition: DirectiveArgumentMetadata) { + this.argumentDirectives.push(definition); + } + collectExtensionsClassMetadata(definition: ExtensionsClassMetadata) { this.classExtensions.push(definition); } + collectExtensionsFieldMetadata(definition: ExtensionsFieldMetadata) { this.fieldExtensions.push(definition); } @@ -123,6 +162,7 @@ export class MetadataStorage { build(options: SchemaGeneratorOptions) { this.classDirectives.reverse(); this.fieldDirectives.reverse(); + this.argumentDirectives.reverse(); this.classExtensions.reverse(); this.fieldExtensions.reverse(); @@ -155,6 +195,7 @@ export class MetadataStorage { this.middlewares = []; this.classDirectives = []; this.fieldDirectives = []; + this.argumentDirectives = []; this.classExtensions = []; this.fieldExtensions = []; @@ -245,12 +286,16 @@ export class MetadataStorage { ); } - const typeField = typeMetadata.fields!.find(fieldDef => fieldDef.name === def.methodName)!; + const typeField = typeMetadata.fields!.find( + fieldDef => fieldDef.schemaName === def.schemaName, + )!; if (!typeField) { const shouldCollectFieldMetadata = !options.resolvers || options.resolvers.some( - resolverCls => resolverCls === def.target || def.target.isPrototypeOf(resolverCls), + resolverCls => + resolverCls === def.target || + Object.prototype.isPrototypeOf.call(def.target, resolverCls), ); if (!def.getType || !def.typeOptions) { throw new NoExplicitTypeError(def.target.name, def.methodName); @@ -291,11 +336,11 @@ export class MetadataStorage { private buildExtendedResolversMetadata() { this.resolverClasses.forEach(def => { - const target = def.target; - let superResolver = Object.getPrototypeOf(target); + let superResolver = Object.getPrototypeOf(def.target); // copy and modify metadata of resolver from parent resolver class while (superResolver.prototype) { + // eslint-disable-next-line @typescript-eslint/no-loop-func const superResolverMetadata = this.resolverClasses.find(it => it.target === superResolver); if (superResolverMetadata) { this.queries = mapSuperResolverHandlers(this.queries, superResolver, def); @@ -317,7 +362,7 @@ export class MetadataStorage { authField => authField.target === target && authField.fieldName === fieldName, ); if (!authorizedField) { - return; + return undefined; } return authorizedField.roles; } @@ -329,7 +374,7 @@ export class MetadataStorage { return storedExtensions .filter( entry => - (entry.target === target || entry.target.isPrototypeOf(target)) && + (entry.target === target || Object.prototype.isPrototypeOf.call(entry.target, target)) && (!("fieldName" in entry) || entry.fieldName === fieldName), ) .reduce((extensions, entry) => ({ ...extensions, ...entry.extensions }), {}); diff --git a/src/metadata/utils.ts b/src/metadata/utils.ts index e2672b416..f0e7718fa 100644 --- a/src/metadata/utils.ts +++ b/src/metadata/utils.ts @@ -1,30 +1,27 @@ +import { ReflectMetadataMissingError } from "@/errors"; +import { isThrowing } from "@/helpers/isThrowing"; +import { type Middleware } from "@/typings/middleware"; import { - ResolverClassMetadata, - BaseResolverMetadata, - MiddlewareMetadata, - FieldResolverMetadata, - ExtensionsClassMetadata, - ExtensionsFieldMetadata, - ExtensionsMetadata, + type BaseResolverMetadata, + type FieldResolverMetadata, + type MiddlewareMetadata, + type ResolverClassMetadata, } from "./definitions"; -import { Middleware } from "../interfaces/Middleware"; -import { isThrowing } from "../helpers/isThrowing"; -import { ReflectMetadataMissingError } from "../errors"; export function mapSuperResolverHandlers( definitions: T[], superResolver: Function, resolverMetadata: ResolverClassMetadata, ): T[] { - return definitions.map(metadata => { - return metadata.target === superResolver + return definitions.map(metadata => + metadata.target === superResolver ? { ...metadata, target: resolverMetadata.target, resolverClassMetadata: resolverMetadata, } - : metadata; - }); + : metadata, + ); } export function mapSuperFieldResolverHandlers( @@ -34,16 +31,16 @@ export function mapSuperFieldResolverHandlers( ) { const superMetadata = mapSuperResolverHandlers(definitions, superResolver, resolverMetadata); - return superMetadata.map(metadata => { - return metadata.target === superResolver + return superMetadata.map(metadata => + metadata.target === superResolver ? { ...metadata, getObjectType: isThrowing(metadata.getObjectType!) ? resolverMetadata.getObjectType : metadata.getObjectType, } - : metadata; - }); + : metadata, + ); } export function mapMiddlewareMetadataToArray( @@ -51,18 +48,13 @@ export function mapMiddlewareMetadataToArray( ): Array> { return metadata .map(m => m.middlewares) - .reduce>>( - (middlewares, resultArray) => resultArray.concat(middlewares), - [], - ); + .reduce< + Array> + >((middlewares, resultArray) => resultArray.concat(middlewares), []); } export function ensureReflectMetadataExists() { - if ( - typeof Reflect !== "object" || - typeof Reflect.decorate !== "function" || - typeof Reflect.metadata !== "function" - ) { + if (typeof Reflect !== "object" || typeof Reflect.getMetadata !== "function") { throw new ReflectMetadataMissingError(); } } diff --git a/src/postinstall.ts b/src/postinstall.ts deleted file mode 100644 index 2d5dce2ba..000000000 --- a/src/postinstall.ts +++ /dev/null @@ -1,27 +0,0 @@ -// tslint:disable -/* Adapted from nodemon's postinstall: https://github.com/remy/nodemon/blob/master/bin/postinstall.js */ - -function printSupportMessage() { - console.log( - "\u001b[32mLove TypeGraphQL or use it at work? \nYou can now support the project via the Open Collective:\u001b[22m\u001b[39m\n > \u001b[96m\u001b[1mhttps://opencollective.com/typegraphql\u001b[0m\n", - ); -} - -if (!process.env.SUPPRESS_SUPPORT) { - try { - const Configstore = require("configstore"); - const pkg = require("../package.json"); - - const now = Date.now(); - const week = 1000 * 60 * 60 * 24 * 7; - const conf = new Configstore(pkg.name); - const last = conf.get("lastCheck"); - - if (!last || now - week > last) { - printSupportMessage(); - conf.set("lastCheck", now); - } - } catch (e) { - printSupportMessage(); - } -} diff --git a/src/resolvers/convert-args.ts b/src/resolvers/convert-args.ts index 37b8c84af..91c7389ff 100644 --- a/src/resolvers/convert-args.ts +++ b/src/resolvers/convert-args.ts @@ -1,8 +1,12 @@ -import { ArgParamMetadata, ClassMetadata, ArgsParamMetadata } from "../metadata/definitions"; -import { convertToType } from "../helpers/types"; -import { ArgsDictionary, ClassType } from "../interfaces"; -import { getMetadataStorage } from "../metadata/getMetadataStorage"; -import { TypeValue } from "../decorators/types"; +import { type TypeValue } from "@/decorators/types"; +import { convertToType } from "@/helpers/types"; +import { + type ArgParamMetadata, + type ArgsParamMetadata, + type ClassMetadata, +} from "@/metadata/definitions"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { type ArgsDictionary, type ClassType } from "@/typings"; interface TransformationTreeField { name: string; @@ -42,7 +46,12 @@ function generateInstanceTransformationTree(target: TypeValue): TransformationTr while (superClass.prototype !== undefined) { const superInputType = getInputType(superClass); if (superInputType) { - inputFields = [...inputFields, ...superInputType.fields!]; + // support overwriting fields of extended types + const existingFieldNames = new Set(inputFields.map(field => field.name)); + const superFields = superInputType.fields!.filter( + field => !existingFieldNames.has(field.name), + ); + inputFields = [...inputFields, ...superFields]; } superClass = Object.getPrototypeOf(superClass); } @@ -88,10 +97,13 @@ function convertToInput(tree: TransformationTree, data: any): any { // don't create property for nullable field if (value !== undefined) { if (value === null || !siblings) { + // eslint-disable-next-line no-param-reassign fields[field.name] = convertToType(field.target, value); } else if (Array.isArray(value)) { + // eslint-disable-next-line no-param-reassign fields[field.name] = value.map(itemValue => convertToInput(siblings, itemValue)); } else { + // eslint-disable-next-line no-param-reassign fields[field.name] = convertToInput(siblings, value); } } @@ -139,6 +151,7 @@ export function convertArgsToInstance(argsMetadata: ArgsParamMetadata, args: Arg // don't create property for nullable field if (fieldValue !== undefined) { const fieldTarget = field.getType(); + // eslint-disable-next-line no-param-reassign fields[field.name] = convertValuesToInstances(fieldTarget, fieldValue); } return fields; diff --git a/src/resolvers/create.ts b/src/resolvers/create.ts index 8be8f27f5..b4fdcc554 100644 --- a/src/resolvers/create.ts +++ b/src/resolvers/create.ts @@ -1,26 +1,25 @@ -import { GraphQLFieldResolver } from "graphql"; - +import { type GraphQLFieldResolver } from "graphql"; +import { AuthMiddleware } from "@/helpers/auth-middleware"; +import { convertToType } from "@/helpers/types"; import { - FieldResolverMetadata, - FieldMetadata, - BaseResolverMetadata, -} from "../metadata/definitions"; -import { getParams, applyMiddlewares, applyAuthChecker } from "./helpers"; -import { convertToType } from "../helpers/types"; -import { BuildContext } from "../schema/build-context"; -import { ResolverData } from "../interfaces"; -import isPromiseLike from "../utils/isPromiseLike"; -import { AuthMiddleware } from "../helpers/auth-middleware"; -import { IOCContainer } from "../utils/container"; + type BaseResolverMetadata, + type FieldMetadata, + type FieldResolverMetadata, +} from "@/metadata/definitions"; +import { BuildContext } from "@/schema/build-context"; +import { type ResolverData } from "@/typings"; +import { type IOCContainer } from "@/utils/container"; +import { isPromiseLike } from "@/utils/isPromiseLike"; +import { applyAuthChecker, applyMiddlewares, getParams } from "./helpers"; export function createHandlerResolver( resolverMetadata: BaseResolverMetadata, ): GraphQLFieldResolver { const { validate: globalValidate, + validateFn, authChecker, authMode, - pubSub, globalMiddlewares, container, } = BuildContext; @@ -40,15 +39,16 @@ export function createHandlerResolver( resolverMetadata.params!, resolverData, globalValidate, - pubSub, + validateFn, ); if (isPromiseLike(params)) { return params.then(resolvedParams => + // eslint-disable-next-line prefer-spread targetInstance[resolverMetadata.methodName].apply(targetInstance, resolvedParams), ); - } else { - return targetInstance[resolverMetadata.methodName].apply(targetInstance, params); } + // eslint-disable-next-line prefer-spread + return targetInstance[resolverMetadata.methodName].apply(targetInstance, params); }), ); } @@ -57,16 +57,17 @@ export function createHandlerResolver( resolverMetadata.params!, resolverData, globalValidate, - pubSub, + validateFn, ); const targetInstance = targetInstanceOrPromise; if (isPromiseLike(params)) { return params.then(resolvedParams => + // eslint-disable-next-line prefer-spread targetInstance[resolverMetadata.methodName].apply(targetInstance, resolvedParams), ); - } else { - return targetInstance[resolverMetadata.methodName].apply(targetInstance, params); } + // eslint-disable-next-line prefer-spread + return targetInstance[resolverMetadata.methodName].apply(targetInstance, params); }); }; } @@ -81,9 +82,9 @@ export function createAdvancedFieldResolver( const targetType = fieldResolverMetadata.getObjectType!(); const { validate: globalValidate, + validateFn, authChecker, authMode, - pubSub, globalMiddlewares, container, } = BuildContext; @@ -104,15 +105,14 @@ export function createAdvancedFieldResolver( fieldResolverMetadata.params!, resolverData, globalValidate, - pubSub, + validateFn, ); if (isPromiseLike(params)) { return params.then(resolvedParams => handlerOrGetterValue.apply(targetInstance, resolvedParams), ); - } else { - return handlerOrGetterValue.apply(targetInstance, params); } + return handlerOrGetterValue.apply(targetInstance, params); }); }; } diff --git a/src/resolvers/helpers.ts b/src/resolvers/helpers.ts index 61bcbe8c6..627cbed6c 100644 --- a/src/resolvers/helpers.ts +++ b/src/resolvers/helpers.ts @@ -1,69 +1,78 @@ -import { PubSubEngine } from "graphql-subscriptions"; - -import { ParamMetadata } from "../metadata/definitions"; -import { convertToType } from "../helpers/types"; +import { AuthMiddleware } from "@/helpers/auth-middleware"; +import { convertToType } from "@/helpers/types"; +import { type ParamMetadata } from "@/metadata/definitions"; +import { type ValidateSettings } from "@/schema/build-context"; +import { type AuthChecker, type AuthMode, type ResolverData, type ValidatorFn } from "@/typings"; +import { type Middleware, type MiddlewareClass, type MiddlewareFn } from "@/typings/middleware"; +import { type IOCContainer } from "@/utils/container"; +import { isPromiseLike } from "@/utils/isPromiseLike"; +import { convertArgToInstance, convertArgsToInstance } from "./convert-args"; import { validateArg } from "./validate-arg"; -import { ResolverData, AuthChecker, AuthMode } from "../interfaces"; -import { Middleware, MiddlewareFn, MiddlewareClass } from "../interfaces/Middleware"; -import { IOCContainer } from "../utils/container"; -import { AuthMiddleware } from "../helpers/auth-middleware"; -import { convertArgsToInstance, convertArgToInstance } from "./convert-args"; -import isPromiseLike from "../utils/isPromiseLike"; -import { ValidateSettings } from "../schema/build-context"; export function getParams( params: ParamMetadata[], resolverData: ResolverData, globalValidate: ValidateSettings, - pubSub: PubSubEngine, + globalValidateFn: ValidatorFn | undefined, ): Promise | any[] { const paramValues = params .sort((a, b) => a.index - b.index) + // eslint-disable-next-line array-callback-return, consistent-return .map(paramInfo => { switch (paramInfo.kind) { case "args": return validateArg( convertArgsToInstance(paramInfo, resolverData.args), paramInfo.getType(), + resolverData, globalValidate, - paramInfo.validate, + paramInfo.validateSettings, + globalValidateFn, + paramInfo.validateFn, ); + case "arg": return validateArg( convertArgToInstance(paramInfo, resolverData.args), paramInfo.getType(), + resolverData, globalValidate, - paramInfo.validate, + paramInfo.validateSettings, + globalValidateFn, + paramInfo.validateFn, ); + case "context": if (paramInfo.propertyName) { return resolverData.context[paramInfo.propertyName]; } return resolverData.context; - case "root": + + case "root": { const rootValue = paramInfo.propertyName ? resolverData.root[paramInfo.propertyName] : resolverData.root; + if (!paramInfo.getType) { return rootValue; } return convertToType(paramInfo.getType(), rootValue); + } + case "info": return resolverData.info; - case "pubSub": - if (paramInfo.triggerKey) { - return (payload: any) => pubSub.publish(paramInfo.triggerKey!, payload); - } - return pubSub; + case "custom": return paramInfo.resolver(resolverData); + + // no default } }); + if (paramValues.some(isPromiseLike)) { return Promise.all(paramValues); - } else { - return paramValues; } + return paramValues; } export function applyAuthChecker( @@ -98,7 +107,7 @@ export function applyMiddlewares( handlerFn = resolverHandlerFunction; } else { const currentMiddleware = middlewares[currentIndex]; - // arrow function or class + // Arrow function or class if (currentMiddleware.prototype !== undefined) { const middlewareClassInstance = await container.getInstance( currentMiddleware as MiddlewareClass, diff --git a/src/resolvers/validate-arg.ts b/src/resolvers/validate-arg.ts index 0710bf01a..948afd613 100644 --- a/src/resolvers/validate-arg.ts +++ b/src/resolvers/validate-arg.ts @@ -1,43 +1,59 @@ -import type { ValidatorOptions } from "class-validator"; -import { TypeValue } from "../decorators/types"; +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore 'class-validator' might not be installed by user +import { type ValidationError, type ValidatorOptions } from "class-validator"; +import { type TypeValue } from "@/decorators/types"; +import { ArgumentValidationError } from "@/errors"; +import { type ValidateSettings } from "@/schema/build-context"; +import { type ResolverData, type ValidatorFn } from "@/typings"; -import { ArgumentValidationError } from "../errors/ArgumentValidationError"; -import { ValidateSettings } from "../schema/build-context"; +const shouldArgBeValidated = (argValue: unknown): boolean => + argValue !== null && typeof argValue === "object"; -export async function validateArg( - argValue: T | undefined, +export async function validateArg( + argValue: any | undefined, argType: TypeValue, - globalValidate: ValidateSettings, - argValidate: ValidateSettings | undefined, -): Promise { - const validate = argValidate !== undefined ? argValidate : globalValidate; - if (validate === false || argValue == null || typeof argValue !== "object") { + resolverData: ResolverData, + globalValidateSettings: ValidateSettings, + argValidateSettings: ValidateSettings | undefined, + globalValidateFn: ValidatorFn | undefined, + argValidateFn: ValidatorFn | undefined, +): Promise { + const validateFn = argValidateFn ?? globalValidateFn; + if (typeof validateFn === "function") { + await validateFn(argValue, argType, resolverData); return argValue; } - if (typeof validate === "function") { - await validate(argValue, argType); + const validate = argValidateSettings !== undefined ? argValidateSettings : globalValidateSettings; + if (validate === false || !shouldArgBeValidated(argValue)) { return argValue; } - const validatorOptions: ValidatorOptions = Object.assign( - {}, - typeof globalValidate === "object" ? globalValidate : {}, - typeof argValidate === "object" ? argValidate : {}, - ); + const validatorOptions: ValidatorOptions = { + ...(typeof globalValidateSettings === "object" ? globalValidateSettings : {}), + ...(typeof argValidateSettings === "object" ? argValidateSettings : {}), + }; if (validatorOptions.skipMissingProperties !== false) { validatorOptions.skipMissingProperties = true; } + if (validatorOptions.forbidUnknownValues !== true) { + validatorOptions.forbidUnknownValues = false; + } + // Dynamic import to avoid making 'class-validator' a peer dependency when `validate: true` is not set const { validateOrReject } = await import("class-validator"); try { if (Array.isArray(argValue)) { - await Promise.all(argValue.map(argItem => validateOrReject(argItem, validatorOptions))); + await Promise.all( + argValue + .filter(shouldArgBeValidated) + .map(argItem => validateOrReject(argItem, validatorOptions)), + ); } else { await validateOrReject(argValue, validatorOptions); } return argValue; } catch (err) { - throw new ArgumentValidationError(err); + throw new ArgumentValidationError(err as ValidationError[]); } } diff --git a/src/scalars/index.ts b/src/scalars/index.ts index 56ecb39de..6304f779f 100644 --- a/src/scalars/index.ts +++ b/src/scalars/index.ts @@ -1,3 +1,2 @@ export * from "./aliases"; -export * from "./isodate"; -export * from "./timestamp"; +export { GraphQLTimestamp, GraphQLDateTimeISO as GraphQLISODateTime } from "graphql-scalars"; diff --git a/src/scalars/isodate.ts b/src/scalars/isodate.ts deleted file mode 100644 index d44d7bda8..000000000 --- a/src/scalars/isodate.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { GraphQLScalarType, Kind } from "graphql"; - -function convertStringToDate(dateString: string) { - try { - return new Date(dateString); - } catch { - throw new Error("Provided date string is invalid and cannot be parsed"); - } -} - -export const GraphQLISODateTime = new GraphQLScalarType({ - name: "DateTime", - description: - "The javascript `Date` as string. Type represents date and time as the ISO Date string.", - serialize(value: unknown) { - if (!(value instanceof Date)) { - throw new Error(`Unable to serialize value '${value}' as it's not an instance of 'Date'`); - } - - return value.toISOString(); - }, - parseValue(value: unknown) { - if (typeof value !== "string") { - throw new Error( - `Unable to parse value '${value}' as GraphQLISODateTime scalar supports only string values`, - ); - } - - return convertStringToDate(value); - }, - parseLiteral(ast) { - if (ast.kind !== Kind.STRING) { - throw new Error( - `Unable to parse literal value of kind '${ast.kind}' as GraphQLISODateTime scalar supports only '${Kind.STRING}' ones`, - ); - } - - return convertStringToDate(ast.value); - }, -}); diff --git a/src/scalars/timestamp.ts b/src/scalars/timestamp.ts deleted file mode 100644 index 8337f7e1e..000000000 --- a/src/scalars/timestamp.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Kind, GraphQLScalarType } from "graphql"; - -function convertTimestampToDate(value: number) { - try { - return new Date(value); - } catch (err) { - throw new Error("Provided date numeric value is invalid and cannot be parsed"); - } -} - -export const GraphQLTimestamp = new GraphQLScalarType({ - name: "Timestamp", - description: - "The javascript `Date` as integer. " + - "Type represents date and time as number of milliseconds from start of UNIX epoch.", - serialize(value: Date) { - if (!(value instanceof Date)) { - throw new Error(`Unable to serialize value '${value}' as it's not an instance of 'Date'`); - } - return value.getTime(); - }, - parseValue(value: unknown) { - if (typeof value !== "number") { - throw new Error( - `Unable to parse value '${value}' as GraphQLTimestamp scalar supports only number values`, - ); - } - - return convertTimestampToDate(value); - }, - parseLiteral(ast) { - if (ast.kind !== Kind.INT) { - throw new Error( - `Unable to parse literal value of kind '${ast.kind}' as GraphQLTimestamp scalar supports only '${Kind.INT}' ones`, - ); - } - - const num = Number.parseInt(ast.value, 10); - return convertTimestampToDate(num); - }, -}); diff --git a/src/schema/build-context.ts b/src/schema/build-context.ts index 0e34106ee..ab3cf3167 100644 --- a/src/schema/build-context.ts +++ b/src/schema/build-context.ts @@ -1,33 +1,34 @@ -import { GraphQLScalarType } from "graphql"; -import type { ValidatorOptions } from "class-validator"; -import { PubSubEngine, PubSub, PubSubOptions } from "graphql-subscriptions"; - -import { AuthChecker, AuthMode } from "../interfaces"; -import { Middleware } from "../interfaces/Middleware"; -import { ContainerType, ContainerGetter, IOCContainer } from "../utils/container"; -import { ValidatorFn } from "../interfaces/ValidatorFn"; - -export type DateScalarMode = "isoDate" | "timestamp"; +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore 'class-validator' might not be installed by user +import { type ValidatorOptions } from "class-validator"; +import { type GraphQLScalarType } from "graphql"; +import { type AuthChecker, type AuthMode } from "@/typings"; +import { type Middleware } from "@/typings/middleware"; +import { type PubSub } from "@/typings/subscriptions"; +import { type ValidatorFn } from "@/typings/ValidatorFn"; +import { type ContainerGetter, type ContainerType, IOCContainer } from "@/utils/container"; export interface ScalarsTypeMap { type: Function; scalar: GraphQLScalarType; } -export type ValidateSettings = boolean | ValidatorOptions | ValidatorFn; +export type ValidateSettings = boolean | ValidatorOptions; export interface BuildContextOptions { - dateScalarMode?: DateScalarMode; scalarsMap?: ScalarsTypeMap[]; /** * Indicates if class-validator should be used to auto validate objects injected into params. * You can directly pass validator options to enable validator with a given options. - * Also, you can provide your own validation function to check the args. */ validate?: ValidateSettings; + /** + * Own validation function to check the args and inputs. + */ + validateFn?: ValidatorFn; authChecker?: AuthChecker; authMode?: AuthMode; - pubSub?: PubSubEngine | PubSubOptions; + pubSub?: PubSub; globalMiddlewares?: Array>; container?: ContainerType | ContainerGetter; /** @@ -41,25 +42,30 @@ export interface BuildContextOptions { } export abstract class BuildContext { - static dateScalarMode: DateScalarMode; static scalarsMaps: ScalarsTypeMap[]; + static validate: ValidateSettings; + + static validateFn?: ValidatorFn; + static authChecker?: AuthChecker; + static authMode: AuthMode; - static pubSub: PubSubEngine; + + static pubSub?: PubSub; + static globalMiddlewares: Array>; + static container: IOCContainer; + static nullableByDefault: boolean; + static disableInferringDefaultValues: boolean; /** * Set static fields with current building context data */ static create(options: BuildContextOptions) { - if (options.dateScalarMode !== undefined) { - this.dateScalarMode = options.dateScalarMode; - } - if (options.scalarsMap !== undefined) { this.scalarsMaps = options.scalarsMap; } @@ -68,6 +74,10 @@ export abstract class BuildContext { this.validate = options.validate; } + if (options.validateFn !== undefined) { + this.validateFn = options.validateFn; + } + if (options.authChecker !== undefined) { this.authChecker = options.authChecker; } @@ -77,11 +87,7 @@ export abstract class BuildContext { } if (options.pubSub !== undefined) { - if ("eventEmitter" in options.pubSub) { - this.pubSub = new PubSub(options.pubSub as PubSubOptions); - } else { - this.pubSub = options.pubSub as PubSubEngine; - } + this.pubSub = options.pubSub; } if (options.globalMiddlewares) { @@ -103,12 +109,12 @@ export abstract class BuildContext { * Restore default settings */ static reset() { - this.dateScalarMode = "isoDate"; this.scalarsMaps = []; - this.validate = true; + this.validate = false; + this.validateFn = undefined; this.authChecker = undefined; this.authMode = "error"; - this.pubSub = new PubSub(); + this.pubSub = undefined; this.globalMiddlewares = []; this.container = new IOCContainer(); this.nullableByDefault = false; @@ -116,5 +122,5 @@ export abstract class BuildContext { } } -// initialize fields +// Initialize fields BuildContext.reset(); diff --git a/src/schema/definition-node.ts b/src/schema/definition-node.ts index 8db5aebc1..f75e5dc2e 100644 --- a/src/schema/definition-node.ts +++ b/src/schema/definition-node.ts @@ -1,32 +1,90 @@ import { - ObjectTypeDefinitionNode, - InputObjectTypeDefinitionNode, - GraphQLOutputType, - FieldDefinitionNode, - GraphQLInputType, - InputValueDefinitionNode, - DirectiveNode, - parseValue, - DocumentNode, + type ConstArgumentNode, + type ConstDirectiveNode, + type DocumentNode, + type FieldDefinitionNode, + type GraphQLInputType, + type GraphQLOutputType, + type InputObjectTypeDefinitionNode, + type InputValueDefinitionNode, + type InterfaceTypeDefinitionNode, + Kind, + type ObjectTypeDefinitionNode, parse, - InterfaceTypeDefinitionNode, + parseConstValue, } from "graphql"; +import { InvalidDirectiveError } from "@/errors"; +import { type DirectiveMetadata } from "@/metadata/definitions"; +import { type SetRequired } from "@/typings"; -import { InvalidDirectiveError } from "../errors"; -import { DirectiveMetadata } from "../metadata/definitions"; +export function getDirectiveNode(directive: DirectiveMetadata): ConstDirectiveNode { + // Inline and trim start + const nameOrDefinition = directive.nameOrDefinition.replaceAll("\n", " ").trimStart(); + const { args } = directive; + + if (nameOrDefinition === "") { + throw new InvalidDirectiveError( + "Please pass at-least one directive name or definition to the @Directive decorator", + ); + } + + if (!nameOrDefinition.startsWith("@")) { + return { + kind: Kind.DIRECTIVE, + name: { + kind: Kind.NAME, + value: nameOrDefinition, + }, + arguments: Object.keys(args).map(argKey => ({ + kind: Kind.ARGUMENT, + name: { + kind: Kind.NAME, + value: argKey, + }, + value: parseConstValue(args[argKey]), + })), + }; + } + + let parsed: DocumentNode; + try { + parsed = parse(`type String ${nameOrDefinition}`); + } catch (err) { + throw new InvalidDirectiveError( + `Error parsing directive definition "${directive.nameOrDefinition}"`, + ); + } + + const definitions = parsed.definitions as ObjectTypeDefinitionNode[]; + const directives = definitions + .filter( + (it): it is SetRequired => + !!it.directives && it.directives.length > 0, + ) + .map(it => it.directives) + .flat(); + + if (directives.length !== 1) { + throw new InvalidDirectiveError( + `Please pass only one directive name or definition at a time to the @Directive decorator "${directive.nameOrDefinition}"`, + ); + } + + return directives[0]; +} export function getObjectTypeDefinitionNode( name: string, directiveMetadata?: DirectiveMetadata[], ): ObjectTypeDefinitionNode | undefined { if (!directiveMetadata || !directiveMetadata.length) { - return; + return undefined; } return { - kind: "ObjectTypeDefinition", + kind: Kind.OBJECT_TYPE_DEFINITION, name: { - kind: "Name", + kind: Kind.NAME, // FIXME: use proper AST representation value: name, }, @@ -39,13 +97,13 @@ export function getInputObjectTypeDefinitionNode( directiveMetadata?: DirectiveMetadata[], ): InputObjectTypeDefinitionNode | undefined { if (!directiveMetadata || !directiveMetadata.length) { - return; + return undefined; } return { - kind: "InputObjectTypeDefinition", + kind: Kind.INPUT_OBJECT_TYPE_DEFINITION, name: { - kind: "Name", + kind: Kind.NAME, // FIXME: use proper AST representation value: name, }, @@ -59,20 +117,20 @@ export function getFieldDefinitionNode( directiveMetadata?: DirectiveMetadata[], ): FieldDefinitionNode | undefined { if (!directiveMetadata || !directiveMetadata.length) { - return; + return undefined; } return { - kind: "FieldDefinition", + kind: Kind.FIELD_DEFINITION, type: { - kind: "NamedType", + kind: Kind.NAMED_TYPE, name: { - kind: "Name", + kind: Kind.NAME, value: type.toString(), }, }, name: { - kind: "Name", + kind: Kind.NAME, value: name, }, directives: directiveMetadata.map(getDirectiveNode), @@ -85,20 +143,20 @@ export function getInputValueDefinitionNode( directiveMetadata?: DirectiveMetadata[], ): InputValueDefinitionNode | undefined { if (!directiveMetadata || !directiveMetadata.length) { - return; + return undefined; } return { - kind: "InputValueDefinition", + kind: Kind.INPUT_VALUE_DEFINITION, type: { - kind: "NamedType", + kind: Kind.NAMED_TYPE, name: { - kind: "Name", + kind: Kind.NAME, value: type.toString(), }, }, name: { - kind: "Name", + kind: Kind.NAME, value: name, }, directives: directiveMetadata.map(getDirectiveNode), @@ -110,66 +168,16 @@ export function getInterfaceTypeDefinitionNode( directiveMetadata?: DirectiveMetadata[], ): InterfaceTypeDefinitionNode | undefined { if (!directiveMetadata || !directiveMetadata.length) { - return; + return undefined; } return { - kind: "InterfaceTypeDefinition", + kind: Kind.INTERFACE_TYPE_DEFINITION, name: { - kind: "Name", + kind: Kind.NAME, // FIXME: use proper AST representation value: name, }, directives: directiveMetadata.map(getDirectiveNode), }; } - -export function getDirectiveNode(directive: DirectiveMetadata): DirectiveNode { - const { nameOrDefinition, args } = directive; - - if (nameOrDefinition === "") { - throw new InvalidDirectiveError( - "Please pass at-least one directive name or definition to the @Directive decorator", - ); - } - - if (!nameOrDefinition.startsWith("@")) { - return { - kind: "Directive", - name: { - kind: "Name", - value: nameOrDefinition, - }, - arguments: Object.keys(args).map(argKey => ({ - kind: "Argument", - name: { - kind: "Name", - value: argKey, - }, - value: parseValue(args[argKey]), - })), - }; - } - - let parsed: DocumentNode; - try { - parsed = parse(`type String ${nameOrDefinition}`); - } catch (err) { - throw new InvalidDirectiveError( - `Error parsing directive definition "${directive.nameOrDefinition}"`, - ); - } - - const definitions = parsed.definitions as ObjectTypeDefinitionNode[]; - const directives = definitions - .filter(it => it.directives && it.directives.length > 0) - .map(it => it.directives!) - .reduce((acc, item) => [...acc, ...item]); // flatten the array - - if (directives.length !== 1) { - throw new InvalidDirectiveError( - `Please pass only one directive name or definition at a time to the @Directive decorator "${directive.nameOrDefinition}"`, - ); - } - return directives[0]; -} diff --git a/src/schema/schema-generator.ts b/src/schema/schema-generator.ts index ffcb2399e..eded919c1 100644 --- a/src/schema/schema-generator.ts +++ b/src/schema/schema-generator.ts @@ -1,53 +1,59 @@ +import { Repeater, filter, pipe } from "@graphql-yoga/subscription"; import { - GraphQLSchema, - GraphQLObjectType, - GraphQLNamedType, - GraphQLFieldConfigMap, - GraphQLOutputType, + type GraphQLDirective, + GraphQLEnumType, + type GraphQLEnumValueConfigMap, + type GraphQLFieldConfigArgumentMap, + type GraphQLFieldConfigMap, + type GraphQLFieldResolver, + type GraphQLInputFieldConfigMap, GraphQLInputObjectType, - GraphQLFieldConfigArgumentMap, - GraphQLInputType, - GraphQLInputFieldConfigMap, + type GraphQLInputType, GraphQLInterfaceType, - graphql, - getIntrospectionQuery, - GraphQLEnumType, - GraphQLEnumValueConfigMap, + type GraphQLNamedType, + GraphQLObjectType, + type GraphQLOutputType, + GraphQLSchema, + type GraphQLTypeResolver, GraphQLUnionType, - GraphQLTypeResolver, - GraphQLDirective, - GraphQLFieldResolver, + getIntrospectionQuery, + graphqlSync, } from "graphql"; -import { withFilter, ResolverFn } from "graphql-subscriptions"; - -import { getMetadataStorage } from "../metadata/getMetadataStorage"; +import { type TypeOptions, type TypeValue } from "@/decorators/types"; import { - ResolverMetadata, - ParamMetadata, - ClassMetadata, - SubscriptionResolverMetadata, - FieldMetadata, -} from "../metadata/definitions"; -import { TypeOptions, TypeValue } from "../decorators/types"; -import { wrapWithTypeOptions, convertTypeIfScalar, getEnumValuesMap } from "../helpers/types"; + CannotDetermineGraphQLTypeError, + ConflictingDefaultValuesError, + GeneratingSchemaError, + InterfaceResolveTypeError, + MissingPubSubError, + MissingSubscriptionTopicsError, + UnionResolveTypeError, +} from "@/errors"; +import { convertTypeIfScalar, getEnumValuesMap, wrapWithTypeOptions } from "@/helpers/types"; +import { + type ClassMetadata, + type FieldMetadata, + type ParamMetadata, + type ResolverMetadata, + type SubscriptionResolverMetadata, +} from "@/metadata/definitions"; +import { type InterfaceClassMetadata } from "@/metadata/definitions/interface-class-metadata"; +import { type ObjectClassMetadata } from "@/metadata/definitions/object-class-metadata"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; import { - createHandlerResolver, createAdvancedFieldResolver, createBasicFieldResolver, + createHandlerResolver, wrapResolverWithAuthChecker, -} from "../resolvers/create"; -import { BuildContext, BuildContextOptions } from "./build-context"; +} from "@/resolvers/create"; import { - UnionResolveTypeError, - GeneratingSchemaError, - MissingSubscriptionTopicsError, - ConflictingDefaultValuesError, - InterfaceResolveTypeError, - CannotDetermineGraphQLTypeError, -} from "../errors"; -import { ResolverFilterData, ResolverTopicData, TypeResolver } from "../interfaces"; -import { getFieldMetadataFromInputType, getFieldMetadataFromObjectType } from "./utils"; -import { ensureInstalledCorrectGraphQLPackage } from "../utils/graphql-version"; + type MaybePromise, + type SubscribeResolverData, + type SubscriptionHandlerData, + type TypeResolver, +} from "@/typings"; +import { ensureInstalledCorrectGraphQLPackage } from "@/utils/graphql-version"; +import { BuildContext, type BuildContextOptions } from "./build-context"; import { getFieldDefinitionNode, getInputObjectTypeDefinitionNode, @@ -55,23 +61,19 @@ import { getInterfaceTypeDefinitionNode, getObjectTypeDefinitionNode, } from "./definition-node"; -import { ObjectClassMetadata } from "../metadata/definitions/object-class-metdata"; -import { InterfaceClassMetadata } from "../metadata/definitions/interface-class-metadata"; +import { getFieldMetadataFromInputType, getFieldMetadataFromObjectType } from "./utils"; -interface AbstractInfo { - isAbstract: boolean; -} -interface ObjectTypeInfo extends AbstractInfo { +interface ObjectTypeInfo { target: Function; type: GraphQLObjectType; metadata: ObjectClassMetadata; } -interface InterfaceTypeInfo extends AbstractInfo { +interface InterfaceTypeInfo { target: Function; type: GraphQLInterfaceType; metadata: InterfaceClassMetadata; } -interface InputObjectTypeInfo extends AbstractInfo { +interface InputObjectTypeInfo { target: Function; type: GraphQLInputObjectType; } @@ -84,11 +86,11 @@ interface UnionTypeInfo { type: GraphQLUnionType; } -export interface SchemaGeneratorOptions extends BuildContextOptions { +export type SchemaGeneratorOptions = { /** * Array of resolvers classes */ - resolvers?: Function[]; + resolvers: Function[]; /** * Array of orphaned type classes that are not used explicitly in GraphQL types definitions */ @@ -101,34 +103,28 @@ export interface SchemaGeneratorOptions extends BuildContextOptions { * Array of graphql directives */ directives?: GraphQLDirective[]; -} +} & BuildContextOptions; export abstract class SchemaGenerator { private static objectTypesInfo: ObjectTypeInfo[] = []; + private static inputTypesInfo: InputObjectTypeInfo[] = []; + private static interfaceTypesInfo: InterfaceTypeInfo[] = []; + private static enumTypesInfo: EnumTypeInfo[] = []; + private static unionTypesInfo: UnionTypeInfo[] = []; - private static usedInterfaceTypes = new Set(); - static async generateFromMetadata(options: SchemaGeneratorOptions): Promise { - const schema = this.generateFromMetadataSync(options); - if (!options.skipCheck) { - const { errors } = await graphql(schema, getIntrospectionQuery()); - if (errors) { - throw new GeneratingSchemaError(errors); - } - } - return schema; - } + private static usedInterfaceTypes = new Set(); - static generateFromMetadataSync(options: SchemaGeneratorOptions): GraphQLSchema { + static generateFromMetadata(options: SchemaGeneratorOptions): GraphQLSchema { this.checkForErrors(options); BuildContext.create(options); getMetadataStorage().build(options); this.buildTypesInfo(options.resolvers); - const orphanedTypes = options.orphanedTypes || (options.resolvers ? [] : undefined); + const orphanedTypes = options.orphanedTypes ?? []; const prebuiltSchema = new GraphQLSchema({ query: this.buildRootQueryType(options.resolvers), mutation: this.buildRootMutationType(options.resolvers), @@ -143,6 +139,14 @@ export abstract class SchemaGenerator { BuildContext.reset(); this.usedInterfaceTypes = new Set(); + + if (!options.skipCheck) { + const { errors } = graphqlSync({ schema: finalSchema, source: getIntrospectionQuery() }); + if (errors) { + throw new GeneratingSchemaError(errors); + } + } + return finalSchema; } @@ -156,7 +160,7 @@ export abstract class SchemaGenerator { } private static getDefaultValue( - typeInstance: { [property: string]: unknown }, + typeInstance: Record, typeOptions: TypeOptions, fieldName: string, typeName: string, @@ -184,7 +188,7 @@ export abstract class SchemaGenerator { : defaultValueFromInitializer; } - private static buildTypesInfo(resolvers?: Function[]) { + private static buildTypesInfo(resolvers: Function[]) { this.unionTypesInfo = getMetadataStorage().unions.map(unionMetadata => { // use closure to capture values from this selected schema build const unionObjectTypesInfo: ObjectTypeInfo[] = []; @@ -237,6 +241,7 @@ export abstract class SchemaGenerator { description: enumMetadata.description, values: Object.keys(enumMap).reduce((enumConfig, enumKey) => { const valueConfig = enumMetadata.valuesConfig[enumKey] || {}; + // eslint-disable-next-line no-param-reassign enumConfig[enumKey] = { value: enumMap[enumKey], description: valueConfig.description, @@ -252,16 +257,15 @@ export abstract class SchemaGenerator { const objectSuperClass = Object.getPrototypeOf(objectType.target); const hasExtended = objectSuperClass.prototype !== undefined; const getSuperClassType = () => { - const superClassTypeInfo = this.objectTypesInfo.find( - type => type.target === objectSuperClass, - ); + const superClassTypeInfo = + this.objectTypesInfo.find(type => type.target === objectSuperClass) ?? + this.interfaceTypesInfo.find(type => type.target === objectSuperClass); return superClassTypeInfo ? superClassTypeInfo.type : undefined; }; const interfaceClasses = objectType.interfaceClasses || []; return { metadata: objectType, target: objectType.target, - isAbstract: objectType.isAbstract || false, type: new GraphQLObjectType({ name: objectType.name, description: objectType.description, @@ -308,18 +312,12 @@ export abstract class SchemaGenerator { let fields = fieldsMetadata.reduce>( (fieldsMap, field) => { - const fieldResolvers = getMetadataStorage().fieldResolvers; - const filteredFieldResolversMetadata = !resolvers - ? fieldResolvers - : fieldResolvers.filter( - it => it.kind === "internal" || resolvers.includes(it.target), - ); + const { fieldResolvers } = getMetadataStorage(); + const filteredFieldResolversMetadata = fieldResolvers.filter( + it => it.kind === "internal" || resolvers.includes(it.target), + ); const fieldResolverMetadata = filteredFieldResolversMetadata.find( - it => - it.getObjectType!() === field.target && - it.methodName === field.name && - (it.resolverClassMetadata === undefined || - it.resolverClassMetadata.isAbstract === false), + it => it.getObjectType!() === field.target && it.methodName === field.name, ); const type = this.getGraphQLOutputType( field.target, @@ -328,19 +326,22 @@ export abstract class SchemaGenerator { field.typeOptions, ); const isSimpleResolver = + // eslint-disable-next-line no-nested-ternary field.simple !== undefined ? field.simple === true : objectType.simpleResolvers !== undefined - ? objectType.simpleResolvers === true - : false; + ? objectType.simpleResolvers === true + : false; + // eslint-disable-next-line no-param-reassign fieldsMap[field.schemaName] = { type, args: this.generateHandlerArgs(field.target, field.name, field.params!), + // eslint-disable-next-line no-nested-ternary resolve: fieldResolverMetadata ? createAdvancedFieldResolver(fieldResolverMetadata) : isSimpleResolver - ? undefined - : createBasicFieldResolver(field), + ? undefined + : createBasicFieldResolver(field), description: field.description, deprecationReason: field.deprecationReason, astNode: getFieldDefinitionNode(field.name, type, field.directives), @@ -359,7 +360,7 @@ export abstract class SchemaGenerator { const superClass = getSuperClassType(); if (superClass) { const superClassFields = getFieldMetadataFromObjectType(superClass); - fields = Object.assign({}, superClassFields, fields); + fields = { ...superClassFields, ...fields }; } } return fields; @@ -394,7 +395,6 @@ export abstract class SchemaGenerator { return { metadata: interfaceType, target: interfaceType.target, - isAbstract: interfaceType.isAbstract || false, type: new GraphQLInterfaceType({ name: interfaceType.name, description: interfaceType.description, @@ -434,9 +434,7 @@ export abstract class SchemaGenerator { const fieldResolverMetadata = getMetadataStorage().fieldResolvers.find( resolver => resolver.getObjectType!() === field.target && - resolver.methodName === field.name && - (resolver.resolverClassMetadata === undefined || - resolver.resolverClassMetadata.isAbstract === false), + resolver.methodName === field.name, ); const type = this.getGraphQLOutputType( field.target, @@ -444,6 +442,7 @@ export abstract class SchemaGenerator { field.getType(), field.typeOptions, ); + // eslint-disable-next-line no-param-reassign fieldsMap[field.schemaName] = { type, args: this.generateHandlerArgs(field.target, field.name, field.params!), @@ -467,7 +466,7 @@ export abstract class SchemaGenerator { const superClass = getSuperClassType(); if (superClass) { const superClassFields = getFieldMetadataFromObjectType(superClass); - fields = Object.assign({}, superClassFields, fields); + fields = { ...superClassFields, ...fields }; } } return fields; @@ -502,7 +501,6 @@ export abstract class SchemaGenerator { const inputInstance = new (inputType.target as any)(); return { target: inputType.target, - isAbstract: inputType.isAbstract || false, type: new GraphQLInputObjectType({ name: inputType.name, description: inputType.description, @@ -521,6 +519,7 @@ export abstract class SchemaGenerator { ...field.typeOptions, defaultValue, }); + // eslint-disable-next-line no-param-reassign fieldsMap[field.name] = { description: field.description, type, @@ -538,7 +537,7 @@ export abstract class SchemaGenerator { const superClass = getSuperClassType(); if (superClass) { const superClassFields = getFieldMetadataFromInputType(superClass); - fields = Object.assign({}, superClassFields, fields); + fields = { ...superClassFields, ...fields }; } } return fields; @@ -549,7 +548,7 @@ export abstract class SchemaGenerator { }); } - private static buildRootQueryType(resolvers?: Function[]): GraphQLObjectType { + private static buildRootQueryType(resolvers: Function[]): GraphQLObjectType { const queriesHandlers = this.filterHandlersByResolvers(getMetadataStorage().queries, resolvers); return new GraphQLObjectType({ @@ -558,13 +557,13 @@ export abstract class SchemaGenerator { }); } - private static buildRootMutationType(resolvers?: Function[]): GraphQLObjectType | undefined { + private static buildRootMutationType(resolvers: Function[]): GraphQLObjectType | undefined { const mutationsHandlers = this.filterHandlersByResolvers( getMetadataStorage().mutations, resolvers, ); if (mutationsHandlers.length === 0) { - return; + return undefined; } return new GraphQLObjectType({ @@ -573,13 +572,13 @@ export abstract class SchemaGenerator { }); } - private static buildRootSubscriptionType(resolvers?: Function[]): GraphQLObjectType | undefined { + private static buildRootSubscriptionType(resolvers: Function[]): GraphQLObjectType | undefined { const subscriptionsHandlers = this.filterHandlersByResolvers( getMetadataStorage().subscriptions, resolvers, ); if (subscriptionsHandlers.length === 0) { - return; + return undefined; } return new GraphQLObjectType({ @@ -588,7 +587,7 @@ export abstract class SchemaGenerator { }); } - private static buildOtherTypes(orphanedTypes?: Function[]): GraphQLNamedType[] { + private static buildOtherTypes(orphanedTypes: Function[]): GraphQLNamedType[] { const autoRegisteredObjectTypesInfo = this.objectTypesInfo.filter(typeInfo => typeInfo.metadata.interfaceClasses?.some(interfaceClass => { const implementedInterfaceInfo = this.interfaceTypesInfo.find( @@ -607,18 +606,9 @@ export abstract class SchemaGenerator { }), ); return [ - ...this.filterTypesInfoByIsAbstractAndOrphanedTypesAndExtractType( - this.objectTypesInfo, - orphanedTypes, - ), - ...this.filterTypesInfoByIsAbstractAndOrphanedTypesAndExtractType( - this.interfaceTypesInfo, - orphanedTypes, - ), - ...this.filterTypesInfoByIsAbstractAndOrphanedTypesAndExtractType( - this.inputTypesInfo, - orphanedTypes, - ), + ...this.filterTypesInfoByOrphanedTypesAndExtractType(this.objectTypesInfo, orphanedTypes), + ...this.filterTypesInfoByOrphanedTypesAndExtractType(this.interfaceTypesInfo, orphanedTypes), + ...this.filterTypesInfoByOrphanedTypesAndExtractType(this.inputTypesInfo, orphanedTypes), ...autoRegisteredObjectTypesInfo.map(typeInfo => typeInfo.type), ]; } @@ -627,16 +617,13 @@ export abstract class SchemaGenerator { handlers: ResolverMetadata[], ): GraphQLFieldConfigMap { return handlers.reduce>((fields, handler) => { - // omit emitting abstract resolver fields - if (handler.resolverClassMetadata && handler.resolverClassMetadata.isAbstract) { - return fields; - } const type = this.getGraphQLOutputType( handler.target, handler.methodName, handler.getReturnType(), handler.returnTypeOptions, ); + // eslint-disable-next-line no-param-reassign fields[handler.schemaName] = { type, args: this.generateHandlerArgs(handler.target, handler.methodName, handler.params!), @@ -653,52 +640,82 @@ export abstract class SchemaGenerator { }, {}); } - private static generateSubscriptionsFields( + private static generateSubscriptionsFields< + TSource extends object = any, + TContext extends object = any, + >( subscriptionsHandlers: SubscriptionResolverMetadata[], - ): GraphQLFieldConfigMap { + ): GraphQLFieldConfigMap { + if (!subscriptionsHandlers.length) { + return {}; + } const { pubSub, container } = BuildContext; + if (!pubSub) { + throw new MissingPubSubError(); + } const basicFields = this.generateHandlerFields(subscriptionsHandlers); - return subscriptionsHandlers.reduce>((fields, handler) => { - // omit emitting abstract resolver fields - if (handler.resolverClassMetadata && handler.resolverClassMetadata.isAbstract) { - return fields; - } + return subscriptionsHandlers.reduce>( + (fields, handler) => { + let subscribeFn: GraphQLFieldResolver< + TSource, + TContext, + any, + MaybePromise> + >; + if (handler.subscribe) { + subscribeFn = (source, args, context, info) => { + const subscribeResolverData: SubscribeResolverData = { source, args, context, info }; + return handler.subscribe!(subscribeResolverData); + }; + } else { + subscribeFn = (source, args, context, info) => { + const subscribeResolverData: SubscribeResolverData = { source, args, context, info }; + + let topics: string | string[]; + if (typeof handler.topics === "function") { + const getTopics = handler.topics; + topics = getTopics(subscribeResolverData); + } else { + topics = handler.topics!; + } + const topicId = handler.topicId?.(subscribeResolverData); + + let pubSubIterable: AsyncIterable; + if (!Array.isArray(topics)) { + pubSubIterable = pubSub.subscribe(topics, topicId); + } else { + if (topics.length === 0) { + throw new MissingSubscriptionTopicsError(handler.target, handler.methodName); + } + pubSubIterable = Repeater.merge([ + ...topics.map(topic => pubSub.subscribe(topic, topicId)), + ]); + } - let subscribeFn: GraphQLFieldResolver; - if (handler.subscribe) { - subscribeFn = handler.subscribe; - } else { - let pubSubIterator: ResolverFn; - if (typeof handler.topics === "function") { - const getTopics = handler.topics; - pubSubIterator = (payload, args, context, info) => { - const resolverTopicData: ResolverTopicData = { payload, args, context, info }; - const topics = getTopics(resolverTopicData); - if (Array.isArray(topics) && topics.length === 0) { - throw new MissingSubscriptionTopicsError(handler.target, handler.methodName); + if (!handler.filter) { + return pubSubIterable; } - return pubSub.asyncIterator(topics); + + return pipe( + pubSubIterable, + filter(payload => { + const handlerData: SubscriptionHandlerData = { payload, args, context, info }; + return handler.filter!(handlerData); + }), + ); }; - } else { - const topics = handler.topics!; - pubSubIterator = () => pubSub.asyncIterator(topics); } - subscribeFn = handler.filter - ? withFilter(pubSubIterator, (payload, args, context, info) => { - const resolverFilterData: ResolverFilterData = { payload, args, context, info }; - return handler.filter!(resolverFilterData); - }) - : pubSubIterator; - } - - fields[handler.schemaName].subscribe = wrapResolverWithAuthChecker( - subscribeFn, - container, - handler.roles, - ); - return fields; - }, basicFields); + // eslint-disable-next-line no-param-reassign + fields[handler.schemaName].subscribe = wrapResolverWithAuthChecker( + subscribeFn, + container, + handler.roles, + ); + return fields; + }, + basicFields, + ); } private static generateHandlerArgs( @@ -708,18 +725,29 @@ export abstract class SchemaGenerator { ): GraphQLFieldConfigArgumentMap { return params!.reduce((args, param) => { if (param.kind === "arg") { + const type = this.getGraphQLInputType( + target, + propertyName, + param.getType(), + param.typeOptions, + param.index, + param.name, + ); + const argDirectives = getMetadataStorage() + .argumentDirectives.filter( + it => + it.target === target && + it.fieldName === propertyName && + it.parameterIndex === param.index, + ) + .map(it => it.directive); + // eslint-disable-next-line no-param-reassign args[param.name] = { description: param.description, - type: this.getGraphQLInputType( - target, - propertyName, - param.getType(), - param.typeOptions, - param.index, - param.name, - ), + type, defaultValue: param.typeOptions.defaultValue, deprecationReason: param.deprecationReason, + astNode: getInputValueDefinitionNode(param.name, type, argDirectives), }; } else if (param.kind === "args") { const argumentType = getMetadataStorage().argumentTypes.find( @@ -731,17 +759,23 @@ export abstract class SchemaGenerator { `is not a class decorated with '@ArgsType' decorator!`, ); } - let superClass = Object.getPrototypeOf(argumentType.target); - while (superClass.prototype !== undefined) { - const superArgumentType = getMetadataStorage().argumentTypes.find( - it => it.target === superClass, + + const inheritanceChainClasses: Function[] = [argumentType.target]; + for ( + let superClass = argumentType.target; + superClass.prototype !== undefined; + superClass = Object.getPrototypeOf(superClass) + ) { + inheritanceChainClasses.push(superClass); + } + for (const argsTypeClass of inheritanceChainClasses.reverse()) { + const inheritedArgumentType = getMetadataStorage().argumentTypes.find( + it => it.target === argsTypeClass, ); - if (superArgumentType) { - this.mapArgFields(superArgumentType, args); + if (inheritedArgumentType) { + this.mapArgFields(inheritedArgumentType, args); } - superClass = Object.getPrototypeOf(superClass); } - this.mapArgFields(argumentType, args); } return args; }, {}); @@ -759,13 +793,17 @@ export abstract class SchemaGenerator { field.name, argumentType.name, ); + const type = this.getGraphQLInputType(field.target, field.name, field.getType(), { + ...field.typeOptions, + defaultValue, + }); + // eslint-disable-next-line no-param-reassign args[field.schemaName] = { description: field.description, - type: this.getGraphQLInputType(field.target, field.name, field.getType(), { - ...field.typeOptions, - defaultValue, - }), + type, defaultValue, + astNode: getInputValueDefinitionNode(field.name, type, field.directives), + extensions: field.extensions, deprecationReason: field.deprecationReason, }; }); @@ -855,7 +893,7 @@ export abstract class SchemaGenerator { return async (...args) => { const resolvedType = await resolveType(...args); if (!resolvedType || typeof resolvedType === "string") { - return resolvedType; + return resolvedType ?? undefined; } return possibleObjectTypesInfo.find(objectType => objectType.target === resolvedType)?.type .name; @@ -864,17 +902,15 @@ export abstract class SchemaGenerator { private static filterHandlersByResolvers( handlers: T[], - resolvers: Function[] | undefined, + resolvers: Function[], ) { - return resolvers ? handlers.filter(query => resolvers.includes(query.target)) : handlers; + return handlers.filter(query => resolvers.includes(query.target)); } - private static filterTypesInfoByIsAbstractAndOrphanedTypesAndExtractType( + private static filterTypesInfoByOrphanedTypesAndExtractType( typesInfo: Array, - orphanedTypes: Function[] | undefined, + orphanedTypes: Function[], ) { - return typesInfo - .filter(it => !it.isAbstract && (!orphanedTypes || orphanedTypes.includes(it.target))) - .map(it => it.type); + return typesInfo.filter(it => orphanedTypes.includes(it.target)).map(it => it.type); } } diff --git a/src/schema/utils.ts b/src/schema/utils.ts index 649dc192d..e08c731d0 100644 --- a/src/schema/utils.ts +++ b/src/schema/utils.ts @@ -1,10 +1,10 @@ import { - GraphQLInputObjectType, - GraphQLInputFieldConfigMap, - GraphQLObjectType, - GraphQLInterfaceType, - GraphQLFieldConfigMap, - GraphQLFieldConfigArgumentMap, + type GraphQLFieldConfigArgumentMap, + type GraphQLFieldConfigMap, + type GraphQLInputFieldConfigMap, + type GraphQLInputObjectType, + type GraphQLInterfaceType, + type GraphQLObjectType, } from "graphql"; export function getFieldMetadataFromInputType(type: GraphQLInputObjectType) { @@ -12,6 +12,7 @@ export function getFieldMetadataFromInputType(type: GraphQLInputObjectType) { const typeFields = Object.keys(fieldInfo).reduce( (fieldsMap, fieldName) => { const superField = fieldInfo[fieldName]; + // eslint-disable-next-line no-param-reassign fieldsMap[fieldName] = { type: superField.type, astNode: superField.astNode, @@ -30,9 +31,11 @@ export function getFieldMetadataFromObjectType(type: GraphQLObjectType | GraphQL const typeFields = Object.keys(fieldInfo).reduce>( (fieldsMap, fieldName) => { const superField = fieldInfo[fieldName]; + // eslint-disable-next-line no-param-reassign fieldsMap[fieldName] = { type: superField.type, args: superField.args.reduce((argMap, { name, ...arg }) => { + // eslint-disable-next-line no-param-reassign argMap[name] = arg; return argMap; }, {}), diff --git a/src/browser-shim.ts b/src/shim.ts similarity index 84% rename from src/browser-shim.ts rename to src/shim.ts index c33a30ae0..2d1645eee 100644 --- a/src/browser-shim.ts +++ b/src/shim.ts @@ -9,7 +9,7 @@ plugins: [ // ...here are any other existing plugins that you already have new webpack.NormalModuleReplacementPlugin(/type-graphql$/, resource => { - resource.request = resource.request.replace(/type-graphql/, "type-graphql/dist/browser-shim"); + resource.request = resource.request.replace(/type-graphql/, "type-graphql/shim"); }), ] ``` @@ -25,21 +25,17 @@ "compilerOptions": { "baseUrl": ".", "paths": { - "type-graphql": [ - "./node_modules/type-graphql/dist/browser-shim.ts" - ] + "type-graphql": ["./node_modules/type-graphql/build/typings/shim.ts"] } } } ``` */ -import * as src from "./index"; +import type * as src from "./index"; export const dummyValue = ""; -export function dummyFn() { - return; -} +export function dummyFn() {} export function dummyDecorator() { return dummyFn; } @@ -48,7 +44,11 @@ export const Arg: typeof src.Arg = dummyDecorator; export const Args: typeof src.Args = dummyDecorator; export const ArgsType: typeof src.ArgsType = dummyDecorator; export const Authorized: typeof src.Authorized = dummyDecorator; +export const createParamDecorator: typeof src.createParamDecorator = dummyFn as any; +export const createMethodDecorator: typeof src.createMethodDecorator = dummyFn as any; export const Ctx: typeof src.Ctx = dummyDecorator; +export const Directive: typeof src.Directive = dummyDecorator; +export const Extensions: typeof src.Extensions = dummyDecorator; export const registerEnumType: typeof src.registerEnumType = dummyFn; export const Field: typeof src.Field = dummyDecorator; export const FieldResolver: typeof src.FieldResolver = dummyDecorator; @@ -57,7 +57,6 @@ export const InputType: typeof src.InputType = dummyDecorator; export const InterfaceType: typeof src.InterfaceType = dummyDecorator; export const Mutation: typeof src.Mutation = dummyDecorator; export const ObjectType: typeof src.ObjectType = dummyDecorator; -export const PubSub: typeof src.PubSub = dummyDecorator; export const Query: typeof src.Query = dummyDecorator; export const Resolver: typeof src.Resolver = dummyDecorator; export const Root: typeof src.Root = dummyDecorator; diff --git a/src/typings/Complexity.ts b/src/typings/Complexity.ts new file mode 100644 index 000000000..e84dfb53a --- /dev/null +++ b/src/typings/Complexity.ts @@ -0,0 +1,3 @@ +import { type ComplexityEstimator } from "graphql-query-complexity"; + +export type Complexity = ComplexityEstimator | number; diff --git a/src/interfaces/ResolverInterface.ts b/src/typings/ResolverInterface.ts similarity index 100% rename from src/interfaces/ResolverInterface.ts rename to src/typings/ResolverInterface.ts diff --git a/src/typings/SubscribeResolverData.ts b/src/typings/SubscribeResolverData.ts new file mode 100644 index 000000000..083b53102 --- /dev/null +++ b/src/typings/SubscribeResolverData.ts @@ -0,0 +1,9 @@ +import { type GraphQLResolveInfo } from "graphql"; +import { type ArgsDictionary } from "./resolver-data"; + +export interface SubscribeResolverData { + source: TSource; + args: TArgs; + context: TContext; + info: GraphQLResolveInfo; +} diff --git a/src/typings/SubscriptionHandlerData.ts b/src/typings/SubscriptionHandlerData.ts new file mode 100644 index 000000000..108720fda --- /dev/null +++ b/src/typings/SubscriptionHandlerData.ts @@ -0,0 +1,9 @@ +import { type GraphQLResolveInfo } from "graphql"; +import { type ArgsDictionary } from "./resolver-data"; + +export interface SubscriptionHandlerData { + payload: TPayload; + args: TArgs; + context: TContext; + info: GraphQLResolveInfo; +} diff --git a/src/interfaces/TypeResolver.ts b/src/typings/TypeResolver.ts similarity index 53% rename from src/interfaces/TypeResolver.ts rename to src/typings/TypeResolver.ts index bb6340355..2ee6981b0 100644 --- a/src/interfaces/TypeResolver.ts +++ b/src/typings/TypeResolver.ts @@ -1,7 +1,5 @@ -import { GraphQLTypeResolver } from "graphql"; - -import { ClassType } from "./ClassType"; -import { MaybePromise, Maybe } from "./Maybe"; +import { type GraphQLTypeResolver } from "graphql"; +import { type ClassType, type Maybe, type MaybePromise } from "./utils"; export type TypeResolver = ( ...args: Parameters> diff --git a/src/typings/ValidatorFn.ts b/src/typings/ValidatorFn.ts new file mode 100644 index 000000000..b82084553 --- /dev/null +++ b/src/typings/ValidatorFn.ts @@ -0,0 +1,17 @@ +import { type TypeValue } from "@/decorators/types"; +import { type ResolverData } from "./resolver-data"; + +export type ValidatorFn = ( + /** + * The value of the argument. + * It can by of any type, which means: + * - undefined or null (if the argument is nullable) + * - primitive type (string, number, boolean) + * - underlying scalar type (Date, Buffer, etc.) + * - object type (arg type class instance) + * - array type (array of any of the above) + */ + argValue: any | undefined, + argType: TypeValue, + resolverData: ResolverData, +) => void | Promise; diff --git a/src/typings/auth-checker.ts b/src/typings/auth-checker.ts new file mode 100644 index 000000000..9f3390100 --- /dev/null +++ b/src/typings/auth-checker.ts @@ -0,0 +1,17 @@ +import { type ResolverData } from "./resolver-data"; +import { type ClassType } from "./utils"; + +export type AuthCheckerFn = ( + resolverData: ResolverData, + roles: TRoleType[], +) => boolean | Promise; + +export interface AuthCheckerInterface { + check(resolverData: ResolverData, roles: TRoleType[]): boolean | Promise; +} + +export type AuthChecker = + | AuthCheckerFn + | ClassType>; + +export type AuthMode = "error" | "null"; diff --git a/src/typings/index.ts b/src/typings/index.ts new file mode 100644 index 000000000..06968c909 --- /dev/null +++ b/src/typings/index.ts @@ -0,0 +1,13 @@ +export * from "./utils"; +export * from "./auth-checker"; +export * from "./Complexity"; +export * from "./legacy-decorators"; +export type { MiddlewareFn, NextFn, MiddlewareInterface } from "./middleware"; +export * from "./resolver-data"; +export * from "./ResolverInterface"; +export * from "./resolvers-map"; +export * from "./SubscribeResolverData"; +export * from "./SubscriptionHandlerData"; +export * from "./subscriptions"; +export * from "./TypeResolver"; +export * from "./ValidatorFn"; diff --git a/src/typings/legacy-decorators.ts b/src/typings/legacy-decorators.ts new file mode 100644 index 000000000..08444328b --- /dev/null +++ b/src/typings/legacy-decorators.ts @@ -0,0 +1,5 @@ +export type ParameterDecorator = ( + target: Object, + propertyKey: string | symbol, // Removed 'undefined' from TS 5.0 + parameterIndex: number, +) => void; diff --git a/src/typings/middleware.ts b/src/typings/middleware.ts new file mode 100644 index 000000000..08af54e0a --- /dev/null +++ b/src/typings/middleware.ts @@ -0,0 +1,19 @@ +import { type ResolverData } from "./resolver-data"; + +export type NextFn = () => Promise; + +export type MiddlewareFn = ( + action: ResolverData, + next: NextFn, +) => Promise; + +export interface MiddlewareInterface { + use: MiddlewareFn; +} +export type MiddlewareClass = new ( + ...args: any[] +) => MiddlewareInterface; + +export type Middleware = + | MiddlewareFn + | MiddlewareClass; diff --git a/src/typings/resolver-data.ts b/src/typings/resolver-data.ts new file mode 100644 index 000000000..7c3372247 --- /dev/null +++ b/src/typings/resolver-data.ts @@ -0,0 +1,10 @@ +import { type GraphQLResolveInfo } from "graphql"; + +export type ArgsDictionary = Record; + +export interface ResolverData { + root: any; + args: ArgsDictionary; + context: TContextType; + info: GraphQLResolveInfo; +} diff --git a/src/typings/resolvers-map.ts b/src/typings/resolvers-map.ts new file mode 100644 index 000000000..3e2354348 --- /dev/null +++ b/src/typings/resolvers-map.ts @@ -0,0 +1,29 @@ +import { + type GraphQLFieldResolver, + type GraphQLIsTypeOfFn, + type GraphQLScalarType, + type GraphQLTypeResolver, +} from "graphql"; + +export type ResolversMap = Record< + string, + | ResolverObject + | ResolverOptions + | GraphQLScalarType + | EnumResolver +>; + +export type ResolverObject = Record< + string, + ResolverOptions | GraphQLFieldResolver +>; + +export type EnumResolver = Record; + +export interface ResolverOptions { + fragment?: string; + resolve?: GraphQLFieldResolver; + subscribe?: GraphQLFieldResolver; + __resolveType?: GraphQLTypeResolver; + __isTypeOf?: GraphQLIsTypeOfFn; +} diff --git a/src/typings/subscriptions.ts b/src/typings/subscriptions.ts new file mode 100644 index 000000000..35e1545e4 --- /dev/null +++ b/src/typings/subscriptions.ts @@ -0,0 +1,10 @@ +export interface PubSub { + /** + * Publish a value for a given topic. + */ + publish(routingKey: string, ...args: unknown[]): void; + /** + * Subscribe to a topic. + */ + subscribe(routingKey: string, dynamicId?: unknown): AsyncIterable; +} diff --git a/src/typings/utils/ClassType.ts b/src/typings/utils/ClassType.ts new file mode 100644 index 000000000..6a4209b8a --- /dev/null +++ b/src/typings/utils/ClassType.ts @@ -0,0 +1,13 @@ +// Copied from 'type-fest' (https://github.com/sindresorhus/type-fest/blob/main/source/basic.d.ts) + +import { type Constructor } from "./Constructor"; + +/** +Matches a [`class`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes). +*/ +export type ClassType = Constructor< + T, + Arguments +> & { + prototype: T; +}; diff --git a/src/typings/utils/Constructor.ts b/src/typings/utils/Constructor.ts new file mode 100644 index 000000000..6ed62b1ef --- /dev/null +++ b/src/typings/utils/Constructor.ts @@ -0,0 +1,8 @@ +// Copied from 'type-fest' (https://github.com/sindresorhus/type-fest/blob/main/source/basic.d.ts) + +/** +Matches a [`class` constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes). +*/ +export type Constructor = new ( + ...arguments_: Arguments +) => T; diff --git a/src/typings/utils/Except.ts b/src/typings/utils/Except.ts new file mode 100644 index 000000000..d9a275230 --- /dev/null +++ b/src/typings/utils/Except.ts @@ -0,0 +1,85 @@ +// Copied from 'type-fest' (https://github.com/sindresorhus/type-fest/blob/main/source/except.d.ts) + +import { type IsEqual } from "./IsEqual"; + +/** +Filter out keys from an object. + +Returns `never` if `Exclude` is strictly equal to `Key`. +Returns `never` if `Key` extends `Exclude`. +Returns `Key` otherwise. + +@example +``` +type Filtered = Filter<'foo', 'foo'>; +//=> never +``` + +@example +``` +type Filtered = Filter<'bar', string>; +//=> never +``` + +@example +``` +type Filtered = Filter<'bar', 'foo'>; +//=> 'bar' +``` +*/ +type Filter = + IsEqual extends true + ? never + : KeyType extends ExcludeType + ? never + : KeyType; + +interface ExceptOptions { + /** + Disallow assigning non-specified properties. + + Note that any omitted properties in the resulting type will be present in autocomplete as `undefined`. + + @defaultValue false + */ + requireExactProps?: boolean; +} + +/** +Create a type from an object type without certain keys. + +We recommend setting the `requireExactProps` option to `true`. + +This type is a stricter version of [`Omit`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-5.html#the-omit-helper-type). The `Omit` type does not restrict the omitted keys to be keys present on the given type, while `Except` does. The benefits of a stricter type are avoiding typos and allowing the compiler to pick up on rename refactors automatically. + +This type was proposed to the TypeScript team, which declined it, saying they prefer that libraries implement stricter versions of the built-in types ([microsoft/TypeScript#30825](https://github.com/microsoft/TypeScript/issues/30825#issuecomment-523668235)). + +@example +``` +import {Except} from 'type-fest'; + +type Foo = { + a: number; + b: string; +}; + +type FooWithoutA = Except; +//=> {b: string} + +const fooWithoutA: FooWithoutA = {a: 1, b: '2'}; +//=> errors: 'a' does not exist in type '{ b: string; }' + +type FooWithoutB = Except; +//=> {a: number} & Partial> + +const fooWithoutB: FooWithoutB = {a: 1, b: '2'}; +//=> errors at 'b': Type 'string' is not assignable to type 'undefined'. +``` +*/ +export type Except< + ObjectType, + KeysType extends keyof ObjectType, + Options extends ExceptOptions = { requireExactProps: false }, +> = { + [KeyType in keyof ObjectType as Filter]: ObjectType[KeyType]; +} & (Options["requireExactProps"] extends true ? Partial> : {}); diff --git a/src/typings/utils/IsEqual.ts b/src/typings/utils/IsEqual.ts new file mode 100644 index 000000000..18a1faf1f --- /dev/null +++ b/src/typings/utils/IsEqual.ts @@ -0,0 +1,27 @@ +// Copied from 'type-fest' (https://github.com/sindresorhus/type-fest/blob/main/source/is-equal.d.ts) + +/** +Returns a boolean for whether the two given types are equal. + +{@link https://github.com/microsoft/TypeScript/issues/27024#issuecomment-421529650} +{@link https://stackoverflow.com/questions/68961864/how-does-the-equals-work-in-typescript/68963796#68963796} + +Use-cases: +- If you want to make a conditional branch based on the result of a comparison of two types. + +@example +``` +import {IsEqual} from 'type-fest'; + +// This type returns a boolean for whether the given array includes the given item. +// `IsEqual` is used to compare the given array at position 0 and the given item and then return true if they are equal. +type Includes = + Value extends readonly [Value[0], ...infer rest] + ? IsEqual extends true + ? true + : Includes + : false; +``` +*/ +export type IsEqual = + (() => G extends A ? 1 : 2) extends () => G extends B ? 1 : 2 ? true : false; diff --git a/src/typings/utils/Maybe.ts b/src/typings/utils/Maybe.ts new file mode 100644 index 000000000..fc44aea9b --- /dev/null +++ b/src/typings/utils/Maybe.ts @@ -0,0 +1 @@ +export type Maybe = T | null | undefined; diff --git a/src/interfaces/Maybe.ts b/src/typings/utils/MaybePromise.ts similarity index 50% rename from src/interfaces/Maybe.ts rename to src/typings/utils/MaybePromise.ts index cdbdd53fc..5eb85a3f9 100644 --- a/src/interfaces/Maybe.ts +++ b/src/typings/utils/MaybePromise.ts @@ -1,3 +1 @@ -export type Maybe = T | null | undefined; - export type MaybePromise = Promise | T; diff --git a/src/typings/utils/MergeExclusive.ts b/src/typings/utils/MergeExclusive.ts new file mode 100644 index 000000000..4272adf8a --- /dev/null +++ b/src/typings/utils/MergeExclusive.ts @@ -0,0 +1,41 @@ +// Copied from 'type-fest' (https://github.com/sindresorhus/type-fest/blob/main/source/merge-exclusive.d.ts) + +// Helper type. Not useful on its own. +type Without = { + [KeyType in Exclude]?: never; +}; + +/** +Create a type that has mutually exclusive keys. + +This type was inspired by [this comment](https://github.com/Microsoft/TypeScript/issues/14094#issuecomment-373782604). + +This type works with a helper type, called `Without`. `Without` produces a type that has only keys from `FirstType` which are not present on `SecondType` and sets the value type for these keys to `never`. This helper type is then used in `MergeExclusive` to remove keys from either `FirstType` or `SecondType`. + +@example +``` +import {MergeExclusive} from 'type-fest'; + +interface ExclusiveVariation1 { + exclusive1: boolean; +} + +interface ExclusiveVariation2 { + exclusive2: string; +} + +type ExclusiveOptions = MergeExclusive; + +let exclusiveOptions: ExclusiveOptions; + +exclusiveOptions = {exclusive1: true}; +//=> Works +exclusiveOptions = {exclusive2: 'hi'}; +//=> Works +exclusiveOptions = {exclusive1: true, exclusive2: 'hi'}; +//=> Error +``` +*/ +export type MergeExclusive = FirstType | SecondType extends object + ? (Without & SecondType) | (Without & FirstType) + : FirstType | SecondType; diff --git a/src/typings/utils/NonEmptyArray.ts b/src/typings/utils/NonEmptyArray.ts new file mode 100644 index 000000000..7b7c1fbe2 --- /dev/null +++ b/src/typings/utils/NonEmptyArray.ts @@ -0,0 +1,3 @@ +// Copied from 'type-fest' (https://github.com/sindresorhus/type-fest/blob/main/source/set-required.d.ts) + +export type NonEmptyArray = readonly [T, ...T[]] | [T, ...T[]]; diff --git a/src/typings/utils/SetRequired.ts b/src/typings/utils/SetRequired.ts new file mode 100644 index 000000000..3154570be --- /dev/null +++ b/src/typings/utils/SetRequired.ts @@ -0,0 +1,34 @@ +// Copied from 'type-fest' (https://github.com/sindresorhus/type-fest/blob/main/source/set-required.d.ts) + +import { type Except } from "./Except"; +import { type Simplify } from "./Simplify"; + +/** +Create a type that makes the given keys required. The remaining keys are kept as is. The sister of the `SetOptional` type. + +Use-case: You want to define a single model where the only thing that changes is whether or not some of the keys are required. + +@example +``` +import {SetRequired} from 'type-fest'; + +type Foo = { + a?: number; + b: string; + c?: boolean; +} + +type SomeRequired = SetRequired; +// type SomeRequired = { +// a?: number; +// b: string; // Was already required and still is. +// c: boolean; // Is now required. +// } +``` +*/ +export type SetRequired = Simplify< + // Pick just the keys that are optional from the base type. + Except & + // Pick the keys that should be required from the base type and make them required. + Required> +>; diff --git a/src/typings/utils/Simplify.ts b/src/typings/utils/Simplify.ts new file mode 100644 index 000000000..7918b1bbc --- /dev/null +++ b/src/typings/utils/Simplify.ts @@ -0,0 +1,58 @@ +// Copied from 'type-fest' (https://github.com/sindresorhus/type-fest/blob/main/source/simplify.d.ts) + +/** +Useful to flatten the type output to improve type hints shown in editors. And also to transform an interface into a type to aide with assignability. + +@example +``` +import {Simplify} from 'type-fest'; + +type PositionProps = { + top: number; + left: number; +}; + +type SizeProps = { + width: number; + height: number; +}; + +// In your editor, hovering over `Props` will show a flattened object with all the properties. +type Props = Simplify; +``` + +Sometimes it is desired to pass a value as a function argument that has a different type. At first inspection it may seem assignable, and then you discover it is not because the `value`'s type definition was defined as an interface. In the following example, `fn` requires an argument of type `Record`. If the value is defined as a literal, then it is assignable. And if the `value` is defined as type using the `Simplify` utility the value is assignable. But if the `value` is defined as an interface, it is not assignable because the interface is not sealed and elsewhere a non-string property could be added to the interface. + +If the type definition must be an interface (perhaps it was defined in a third-party npm package), then the `value` can be defined as `const value: Simplify = ...`. Then `value` will be assignable to the `fn` argument. Or the `value` can be cast as `Simplify` if you can't re-declare the `value`. + +@example +``` +import {Simplify} from 'type-fest'; + +interface SomeInterface { + foo: number; + bar?: string; + baz: number | undefined; +} + +type SomeType = { + foo: number; + bar?: string; + baz: number | undefined; +}; + +const literal = {foo: 123, bar: 'hello', baz: 456}; +const someType: SomeType = literal; +const someInterface: SomeInterface = literal; + +function fn(object: Record): void {} + +fn(literal); // Good: literal object type is sealed +fn(someType); // Good: type is sealed +fn(someInterface); // Error: Index signature for type 'string' is missing in type 'someInterface'. Because `interface` can be re-opened +fn(someInterface as Simplify); // Good: transform an `interface` into a `type` +``` + +{@link https://github.com/microsoft/TypeScript/issues/15300} +*/ +export type Simplify = { [KeyType in keyof T]: T[KeyType] } & {}; diff --git a/src/typings/utils/index.ts b/src/typings/utils/index.ts new file mode 100644 index 000000000..4eb054327 --- /dev/null +++ b/src/typings/utils/index.ts @@ -0,0 +1,10 @@ +export * from "./ClassType"; +export * from "./Constructor"; +export * from "./Except"; +export * from "./IsEqual"; +export * from "./Maybe"; +export * from "./MaybePromise"; +export * from "./MergeExclusive"; +export * from "./NonEmptyArray"; +export * from "./SetRequired"; +export * from "./Simplify"; diff --git a/src/utils/buildSchema.ts b/src/utils/buildSchema.ts index ae361bc16..0ea09aeac 100644 --- a/src/utils/buildSchema.ts +++ b/src/utils/buildSchema.ts @@ -1,84 +1,77 @@ -import { GraphQLSchema } from "graphql"; -import path from "path"; - -import { SchemaGenerator, SchemaGeneratorOptions } from "../schema/schema-generator"; -import { loadResolversFromGlob } from "../helpers/loadResolversFromGlob"; +import path from "node:path"; +import { type GraphQLSchema } from "graphql"; +import { SchemaGenerator, type SchemaGeneratorOptions } from "@/schema/schema-generator"; +import { type NonEmptyArray } from "@/typings"; import { - emitSchemaDefinitionFileSync, - emitSchemaDefinitionFile, + type PrintSchemaOptions, defaultPrintSchemaOptions, - PrintSchemaOptions, + emitSchemaDefinitionFile, + emitSchemaDefinitionFileSync, } from "./emitSchemaDefinitionFile"; -import { NonEmptyArray } from "../interfaces/NonEmptyArray"; -interface EmitSchemaFileOptions extends Partial { +type EmitSchemaFileOptions = { path?: string; +} & Partial; + +function getEmitSchemaDefinitionFileOptions(buildSchemaOptions: BuildSchemaOptions): { + schemaFileName: string; + printSchemaOptions: PrintSchemaOptions; +} { + const defaultSchemaFilePath = path.resolve(process.cwd(), "schema.graphql"); + + return { + schemaFileName: + // eslint-disable-next-line no-nested-ternary + typeof buildSchemaOptions.emitSchemaFile === "string" + ? buildSchemaOptions.emitSchemaFile + : typeof buildSchemaOptions.emitSchemaFile === "object" + ? buildSchemaOptions.emitSchemaFile.path || defaultSchemaFilePath + : defaultSchemaFilePath, + printSchemaOptions: + typeof buildSchemaOptions.emitSchemaFile === "object" + ? { ...defaultPrintSchemaOptions, ...buildSchemaOptions.emitSchemaFile } + : defaultPrintSchemaOptions, + }; +} + +function loadResolvers(options: BuildSchemaOptions): Function[] { + // Additional runtime check as it should be covered by the `NonEmptyArray` type guard + if (options.resolvers.length === 0) { + throw new Error("Empty `resolvers` array property found in `buildSchema` options!"); + } + + return options.resolvers as Function[]; } -export interface BuildSchemaOptions extends Omit { - /** Array of resolvers classes or glob paths to resolver files */ - resolvers: NonEmptyArray | NonEmptyArray; +export type BuildSchemaOptions = { + /** Array of resolvers classes to resolver files */ + resolvers: NonEmptyArray; /** * Path to the file to where emit the schema * or config object with print schema options - * or `true` for the default `./schema.gql` one + * or `true` for the default `./schema.graphql` one */ emitSchemaFile?: string | boolean | EmitSchemaFileOptions; -} +} & Omit; export async function buildSchema(options: BuildSchemaOptions): Promise { const resolvers = loadResolvers(options); - const schema = await SchemaGenerator.generateFromMetadata({ ...options, resolvers }); + const schema = SchemaGenerator.generateFromMetadata({ ...options, resolvers }); if (options.emitSchemaFile) { const { schemaFileName, printSchemaOptions } = getEmitSchemaDefinitionFileOptions(options); await emitSchemaDefinitionFile(schemaFileName, schema, printSchemaOptions); } + return schema; } export function buildSchemaSync(options: BuildSchemaOptions): GraphQLSchema { const resolvers = loadResolvers(options); - const schema = SchemaGenerator.generateFromMetadataSync({ ...options, resolvers }); + const schema = SchemaGenerator.generateFromMetadata({ ...options, resolvers }); if (options.emitSchemaFile) { const { schemaFileName, printSchemaOptions } = getEmitSchemaDefinitionFileOptions(options); emitSchemaDefinitionFileSync(schemaFileName, schema, printSchemaOptions); } - return schema; -} -function loadResolvers(options: BuildSchemaOptions): Function[] | undefined { - // TODO: remove that check as it's covered by `NonEmptyArray` type guard - if (options.resolvers.length === 0) { - throw new Error("Empty `resolvers` array property found in `buildSchema` options!"); - } - if (options.resolvers.some((resolver: Function | string) => typeof resolver === "string")) { - (options.resolvers as string[]).forEach(resolver => { - if (typeof resolver === "string") { - loadResolversFromGlob(resolver); - } - }); - return undefined; - } - return options.resolvers as Function[]; -} - -function getEmitSchemaDefinitionFileOptions( - buildSchemaOptions: BuildSchemaOptions, -): { - schemaFileName: string; - printSchemaOptions: PrintSchemaOptions; -} { - const defaultSchemaFilePath = path.resolve(process.cwd(), "schema.gql"); - return { - schemaFileName: - typeof buildSchemaOptions.emitSchemaFile === "string" - ? buildSchemaOptions.emitSchemaFile - : typeof buildSchemaOptions.emitSchemaFile === "object" - ? buildSchemaOptions.emitSchemaFile.path || defaultSchemaFilePath - : defaultSchemaFilePath, - printSchemaOptions: - typeof buildSchemaOptions.emitSchemaFile === "object" - ? { ...defaultPrintSchemaOptions, ...buildSchemaOptions.emitSchemaFile } - : defaultPrintSchemaOptions, - }; + return schema; } diff --git a/src/utils/buildTypeDefsAndResolvers.ts b/src/utils/buildTypeDefsAndResolvers.ts index 5c0ada7ab..94e733e59 100644 --- a/src/utils/buildTypeDefsAndResolvers.ts +++ b/src/utils/buildTypeDefsAndResolvers.ts @@ -1,8 +1,13 @@ -import { GraphQLSchema, printSchema } from "graphql"; - -import { BuildSchemaOptions, buildSchema, buildSchemaSync } from "./buildSchema"; +import { type GraphQLSchema, printSchema } from "graphql"; +import { type BuildSchemaOptions, buildSchema, buildSchemaSync } from "./buildSchema"; import { createResolversMap } from "./createResolversMap"; +function createTypeDefsAndResolversMap(schema: GraphQLSchema) { + const typeDefs = printSchema(schema); + const resolvers = createResolversMap(schema); + return { typeDefs, resolvers }; +} + export async function buildTypeDefsAndResolvers(options: BuildSchemaOptions) { const schema = await buildSchema(options); return createTypeDefsAndResolversMap(schema); @@ -12,9 +17,3 @@ export function buildTypeDefsAndResolversSync(options: BuildSchemaOptions) { const schema = buildSchemaSync(options); return createTypeDefsAndResolversMap(schema); } - -function createTypeDefsAndResolversMap(schema: GraphQLSchema) { - const typeDefs = printSchema(schema); - const resolvers = createResolversMap(schema); - return { typeDefs, resolvers }; -} diff --git a/src/utils/container.ts b/src/utils/container.ts index 2bb6c8a60..467082e6a 100644 --- a/src/utils/container.ts +++ b/src/utils/container.ts @@ -1,6 +1,7 @@ -import { ResolverData } from "../interfaces"; +/* eslint-disable max-classes-per-file */ +import { type ResolverData } from "@/typings"; -export type SupportedType = { new (...args: any[]): T } | Function; +export type SupportedType = (new (...args: any[]) => T) | Function; export interface ContainerType { get(someClass: any, resolverData: ResolverData): any | Promise; @@ -31,7 +32,9 @@ class DefaultContainer { export class IOCContainer { private container: ContainerType | undefined; + private containerGetter: ContainerGetter | undefined; + private defaultContainer = new DefaultContainer(); constructor(iocContainerOrContainerGetter?: ContainerType | ContainerGetter) { diff --git a/src/utils/createResolversMap.ts b/src/utils/createResolversMap.ts index 145ae0962..8c5acfdfa 100644 --- a/src/utils/createResolversMap.ts +++ b/src/utils/createResolversMap.ts @@ -1,21 +1,56 @@ +/* eslint-disable no-param-reassign */ import { - GraphQLScalarType, + type GraphQLAbstractType, GraphQLEnumType, - GraphQLObjectType, + type GraphQLFieldMap, GraphQLInterfaceType, + GraphQLObjectType, + GraphQLScalarType, + type GraphQLSchema, + type GraphQLTypeResolver, GraphQLUnionType, - GraphQLFieldMap, - GraphQLSchema, - GraphQLTypeResolver, - GraphQLAbstractType, } from "graphql"; +import { type EnumResolver, type ResolverObject, type ResolversMap } from "@/typings"; + +function generateTypeResolver( + abstractType: GraphQLAbstractType, + schema: GraphQLSchema, +): GraphQLTypeResolver { + if (abstractType.resolveType) { + return abstractType.resolveType; + } + + const possibleObjectTypes = schema.getPossibleTypes(abstractType); + return async (source, context, info) => { + for (const objectType of possibleObjectTypes) { + // eslint-disable-next-line no-await-in-loop + if (objectType.isTypeOf && (await objectType.isTypeOf(source, context, info))) { + return objectType.name; + } + } + return undefined; + }; +} -import { ResolversMap, EnumResolver, ResolverObject } from "../interfaces"; +function generateFieldsResolvers(fields: GraphQLFieldMap): ResolverObject { + return Object.keys(fields).reduce((fieldsMap, fieldName) => { + const field = fields[fieldName]; + if (field.subscribe) { + fieldsMap[fieldName] = { + subscribe: field.subscribe, + resolve: field.resolve, + }; + } else if (field.resolve) { + fieldsMap[fieldName] = field.resolve; + } + return fieldsMap; + }, {}); +} export function createResolversMap(schema: GraphQLSchema): ResolversMap { const typeMap = schema.getTypeMap(); return Object.keys(typeMap) - .filter(typeName => !typeName.includes("__")) + .filter(typeName => !typeName.startsWith("__")) .reduce((resolversMap, typeName) => { const type = typeMap[typeName]; if (type instanceof GraphQLObjectType) { @@ -50,43 +85,3 @@ export function createResolversMap(schema: GraphQLSchema): ResolversMap { return resolversMap; }, {}); } - -function generateTypeResolver( - abstractType: GraphQLAbstractType, - schema: GraphQLSchema, -): GraphQLTypeResolver { - if (abstractType.resolveType) { - return async (...args) => { - const detectedType = await abstractType.resolveType!(...args); - if (detectedType instanceof GraphQLObjectType) { - return detectedType.name; - } - return detectedType; - }; - } - - const possibleObjectTypes = schema.getPossibleTypes(abstractType); - return async (source, context, info) => { - for (const objectType of possibleObjectTypes) { - if (objectType.isTypeOf && (await objectType.isTypeOf(source, context, info))) { - return objectType.name; - } - } - return null; - }; -} - -function generateFieldsResolvers(fields: GraphQLFieldMap): ResolverObject { - return Object.keys(fields).reduce((fieldsMap, fieldName) => { - const field = fields[fieldName]; - if (field.subscribe) { - fieldsMap[fieldName] = { - subscribe: field.subscribe, - resolve: field.resolve, - }; - } else if (field.resolve) { - fieldsMap[fieldName] = field.resolve; - } - return fieldsMap; - }, {}); -} diff --git a/src/utils/emitSchemaDefinitionFile.ts b/src/utils/emitSchemaDefinitionFile.ts index 2da48bf33..1a06c9507 100644 --- a/src/utils/emitSchemaDefinitionFile.ts +++ b/src/utils/emitSchemaDefinitionFile.ts @@ -1,14 +1,11 @@ -import { GraphQLSchema, printSchema, lexicographicSortSchema } from "graphql"; -import { Options as GraphQLPrintSchemaOptions } from "graphql/utilities/printSchema"; +import { type GraphQLSchema, lexicographicSortSchema, printSchema } from "graphql"; +import { outputFile, outputFileSync } from "@/helpers/filesystem"; -import { outputFile, outputFileSync } from "../helpers/filesystem"; - -export interface PrintSchemaOptions extends Required { +export interface PrintSchemaOptions { sortedSchema: boolean; } export const defaultPrintSchemaOptions: PrintSchemaOptions = { - commentDescriptions: false, sortedSchema: true, }; @@ -20,6 +17,11 @@ const generatedSchemaWarning = /* graphql */ `\ `; +function getSchemaFileContent(schema: GraphQLSchema, options: PrintSchemaOptions) { + const schemaToEmit = options.sortedSchema ? lexicographicSortSchema(schema) : schema; + return generatedSchemaWarning + printSchema(schemaToEmit); +} + export function emitSchemaDefinitionFileSync( schemaFilePath: string, schema: GraphQLSchema, @@ -37,8 +39,3 @@ export async function emitSchemaDefinitionFile( const schemaFileContent = getSchemaFileContent(schema, options); await outputFile(schemaFilePath, schemaFileContent); } - -function getSchemaFileContent(schema: GraphQLSchema, options: PrintSchemaOptions) { - const schemaToEmit = options.sortedSchema ? lexicographicSortSchema(schema) : schema; - return generatedSchemaWarning + printSchema(schemaToEmit, options); -} diff --git a/src/utils/graphql-version.ts b/src/utils/graphql-version.ts index 0fd6c0eb4..56c473795 100644 --- a/src/utils/graphql-version.ts +++ b/src/utils/graphql-version.ts @@ -1,22 +1,13 @@ +import * as graphql from "graphql"; import semVer from "semver"; - +// Avoid '@/' due to 'scripts/version.ts' import { UnmetGraphQLPeerDependencyError } from "../errors"; -export function getInstalledGraphQLVersion(): string { - const graphqlPackageJson = require("graphql/package.json"); - return graphqlPackageJson.version; -} - -export function getPeerDependencyGraphQLRequirement(): string { - const ownPackageJson = require("../../package.json"); - return ownPackageJson.peerDependencies.graphql; -} +// This must be kept in sync with 'package.json' +export const graphQLPeerDependencyVersion = "^16.8.1"; export function ensureInstalledCorrectGraphQLPackage() { - const installedVersion = getInstalledGraphQLVersion(); - const versionRequirement = getPeerDependencyGraphQLRequirement(); - - if (!semVer.satisfies(installedVersion, versionRequirement)) { - throw new UnmetGraphQLPeerDependencyError(); + if (!semVer.satisfies(graphql.version, graphQLPeerDependencyVersion)) { + throw new UnmetGraphQLPeerDependencyError(graphql.version, graphQLPeerDependencyVersion); } } diff --git a/src/utils/index.ts b/src/utils/index.ts index fae4db30f..e3168f515 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,13 +1,15 @@ -export { buildSchema, buildSchemaSync, BuildSchemaOptions } from "./buildSchema"; +export type { BuildSchemaOptions } from "./buildSchema"; +export { buildSchema, buildSchemaSync } from "./buildSchema"; export { buildTypeDefsAndResolvers, buildTypeDefsAndResolversSync, } from "./buildTypeDefsAndResolvers"; +export type { ContainerType, ContainerGetter } from "./container"; export { createResolversMap } from "./createResolversMap"; +export type { PrintSchemaOptions } from "./emitSchemaDefinitionFile"; export { emitSchemaDefinitionFile, emitSchemaDefinitionFileSync, - PrintSchemaOptions, defaultPrintSchemaOptions, } from "./emitSchemaDefinitionFile"; -export { ContainerType, ContainerGetter } from "./container"; +export * from "./graphql-version"; diff --git a/src/utils/isPromiseLike.ts b/src/utils/isPromiseLike.ts index 1a9743f3b..729b3a1d6 100644 --- a/src/utils/isPromiseLike.ts +++ b/src/utils/isPromiseLike.ts @@ -1,4 +1,4 @@ -export default function isPromiseLike( +export function isPromiseLike( value: PromiseLike | TValue, ): value is PromiseLike { return value != null && typeof (value as PromiseLike).then === "function"; diff --git a/src/utils/types.ts b/src/utils/types.ts deleted file mode 100644 index c6bd3570b..000000000 --- a/src/utils/types.ts +++ /dev/null @@ -1,10 +0,0 @@ -// `Without` and `MergeExclusive` copied from `sindresorhus/type-fest` -// https://github.com/sindresorhus/type-fest/blob/c6a3d8c2603e9d6b8f20edb0157faae15548cd5b/source/merge-exclusive.d.ts - -export type Without = { - [KeyType in Exclude]?: never; -}; - -export type MergeExclusive = FirstType | SecondType extends object - ? (Without & SecondType) | (Without & FirstType) - : FirstType | SecondType; diff --git a/tests/.eslintrc b/tests/.eslintrc new file mode 100644 index 000000000..9c5c6a31d --- /dev/null +++ b/tests/.eslintrc @@ -0,0 +1,15 @@ +{ + "env": { + "jest/globals": true + }, + "rules": { + "max-classes-per-file": "off", + "class-methods-use-this": "off", + "import/no-extraneous-dependencies": [ + "error", + { + "devDependencies": true + } + ] + } +} diff --git a/tests/functional/authorization.ts b/tests/functional/authorization.ts index 640b3e8dc..01d9681e1 100644 --- a/tests/functional/authorization.ts +++ b/tests/functional/authorization.ts @@ -1,21 +1,21 @@ import "reflect-metadata"; -import { GraphQLSchema, graphql } from "graphql"; - -import { getMetadataStorage } from "../../src/metadata/getMetadataStorage"; +import { type GraphQLSchema, graphql } from "graphql"; import { + type AuthCheckerInterface, + AuthenticationError, + AuthorizationError, + Authorized, + Ctx, Field, + FieldResolver, ObjectType, - Ctx, - Authorized, Query, Resolver, + type ResolverData, buildSchema, - FieldResolver, - UnauthorizedError, - ForbiddenError, - AuthCheckerInterface, - ResolverData, -} from "../../src"; +} from "type-graphql"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { expectToThrow } from "../helpers/expectToThrow"; describe("Authorization", () => { let schema: GraphQLSchema; @@ -27,32 +27,32 @@ describe("Authorization", () => { @ObjectType() class SampleObject { @Field() - normalField: string; + normalField!: string; @Field() @Authorized() - authedField: string; + authedField!: string; @Field({ nullable: true }) @Authorized() - nullableAuthedField: string; + nullableAuthedField!: string; @Field() @Authorized("ADMIN") - adminField: string; + adminField!: string; @Field() - normalResolvedField: string; + normalResolvedField!: string; @Field() - authedResolvedField: string; + authedResolvedField!: string; @Field() @Authorized() - inlineAuthedResolvedField: string; + inlineAuthedResolvedField!: string; } - @Resolver(of => SampleObject) + @Resolver(() => SampleObject) class SampleResolver { @Query() normalQuery(): boolean { @@ -74,9 +74,9 @@ describe("Authorization", () => { return ctx.user !== undefined; } - @Query(type => Boolean, { nullable: true }) + @Query(() => Boolean, { nullable: true }) @Authorized() - nullableAuthedQuery(@Ctx() ctx: any) { + nullableAuthedQuery() { return true; } @@ -173,15 +173,14 @@ describe("Authorization", () => { describe("Errors", () => { it("should throw error when `@Authorized` is used and no `authChecker` provided", async () => { - expect.assertions(2); - try { - await buildSchema({ + const error = await expectToThrow(() => + buildSchema({ resolvers: [sampleResolver], - }); - } catch (err) { - expect(err).toBeDefined(); - expect(err.message).toContain("authChecker"); - } + }), + ); + + expect(error).toBeDefined(); + expect(error.message).toContain("authChecker"); }); // TODO: check for wrong `@Authorized` usage @@ -203,7 +202,7 @@ describe("Authorization", () => { normalQuery }`; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); expect(result.data!.normalQuery).toEqual(true); }); @@ -215,7 +214,7 @@ describe("Authorization", () => { } }`; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); expect(result.data!.normalObjectQuery.normalField).toEqual("normalField"); }); @@ -227,7 +226,7 @@ describe("Authorization", () => { } }`; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); expect(result.data!.normalObjectQuery.normalResolvedField).toEqual("normalResolvedField"); }); @@ -241,7 +240,7 @@ describe("Authorization", () => { authedQuery }`; - const result = await graphql(localSchema, query); + const result: any = await graphql({ schema: localSchema, source: query }); expect(result.data).toBeNull(); expect(result.errors).toBeDefined(); @@ -257,13 +256,13 @@ describe("Authorization", () => { nullableAuthedQuery }`; - const result = await graphql(localSchema, query); + const result: any = await graphql({ schema: localSchema, source: query }); expect(result.data!.nullableAuthedQuery).toBeNull(); expect(result.errors).toBeUndefined(); }); - it("should throw UnauthorizedError when guest accessing authed query", async () => { + it("should throw AuthenticationError when guest accessing authed query", async () => { const localSchema = await buildSchema({ resolvers: [sampleResolver], authChecker: () => false, @@ -272,16 +271,16 @@ describe("Authorization", () => { authedQuery }`; - const result = await graphql(localSchema, query); + const result: any = await graphql({ schema: localSchema, source: query }); expect(result.data).toBeNull(); expect(result.errors).toHaveLength(1); const error = result.errors![0]; - expect(error.originalError).toBeInstanceOf(UnauthorizedError); + expect(error.originalError).toBeInstanceOf(AuthenticationError); expect(error.path).toContain("authedQuery"); }); - it("should throw ForbiddenError when guest accessing query authed with roles", async () => { + it("should throw AuthorizationError when guest accessing query authed with roles", async () => { const localSchema = await buildSchema({ resolvers: [sampleResolver], authChecker: () => false, @@ -290,12 +289,12 @@ describe("Authorization", () => { adminQuery }`; - const result = await graphql(localSchema, query); + const result: any = await graphql({ schema: localSchema, source: query }); expect(result.data).toBeNull(); expect(result.errors).toHaveLength(1); const error = result.errors![0]; - expect(error.originalError).toBeInstanceOf(ForbiddenError); + expect(error.originalError).toBeInstanceOf(AuthorizationError); expect(error.path).toContain("adminQuery"); }); @@ -308,7 +307,7 @@ describe("Authorization", () => { authedQuery }`; - const result = await graphql(localSchema, query, null, {}); + const result: any = await graphql({ schema: localSchema, source: query, contextValue: {} }); expect(result.data!.authedQuery).toEqual(false); }); @@ -324,7 +323,7 @@ describe("Authorization", () => { } }`; - const result = await graphql(localSchema, query); + const result: any = await graphql({ schema: localSchema, source: query }); expect(result.data).toBeNull(); }); @@ -340,12 +339,12 @@ describe("Authorization", () => { } }`; - const result = await graphql(localSchema, query); + const result: any = await graphql({ schema: localSchema, source: query }); expect(result.data!.normalObjectQuery.nullableAuthedField).toBeNull(); }); - it("should throw UnauthorizedError when guest accessing autherd object field", async () => { + it("should throw AuthenticationError when guest accessing authed object field", async () => { const localSchema = await buildSchema({ resolvers: [sampleResolver], authChecker: () => false, @@ -356,16 +355,16 @@ describe("Authorization", () => { } }`; - const result = await graphql(localSchema, query); + const result: any = await graphql({ schema: localSchema, source: query }); expect(result.data).toBeNull(); expect(result.errors).toHaveLength(1); const error = result.errors![0]; - expect(error.originalError).toBeInstanceOf(UnauthorizedError); + expect(error.originalError).toBeInstanceOf(AuthenticationError); expect(error.path).toContain("authedField"); }); - it("should throw ForbiddenError when guest accessing object field authed with roles", async () => { + it("should throw AuthorizationError when guest accessing object field authed with roles", async () => { const localSchema = await buildSchema({ resolvers: [sampleResolver], authChecker: () => false, @@ -376,12 +375,12 @@ describe("Authorization", () => { } }`; - const result = await graphql(localSchema, query); + const result: any = await graphql({ schema: localSchema, source: query }); expect(result.data).toBeNull(); expect(result.errors).toHaveLength(1); const error = result.errors![0]; - expect(error.originalError).toBeInstanceOf(ForbiddenError); + expect(error.originalError).toBeInstanceOf(AuthorizationError); expect(error.path).toContain("adminField"); }); @@ -396,7 +395,7 @@ describe("Authorization", () => { } }`; - const result = await graphql(localSchema, query, null, {}); + const result: any = await graphql({ schema: localSchema, source: query, contextValue: {} }); expect(result.data!.normalObjectQuery.authedField).toEqual("authedField"); }); @@ -412,7 +411,7 @@ describe("Authorization", () => { } }`; - const result = await graphql(localSchema, query); + const result: any = await graphql({ schema: localSchema, source: query }); expect(result.data).toBeNull(); }); @@ -428,7 +427,7 @@ describe("Authorization", () => { } }`; - const result = await graphql(localSchema, query); + const result: any = await graphql({ schema: localSchema, source: query }); expect(result.data).toBeNull(); }); @@ -444,7 +443,7 @@ describe("Authorization", () => { } }`; - const result = await graphql(localSchema, query, null, {}); + const result: any = await graphql({ schema: localSchema, source: query, contextValue: {} }); expect(result.data!.normalObjectQuery.inlineAuthedResolvedField).toEqual( "inlineAuthedResolvedField", @@ -455,7 +454,7 @@ describe("Authorization", () => { let authCheckerRoles: string[] | undefined; const localSchema = await buildSchema({ resolvers: [sampleResolver], - authChecker: (resolverData, roles) => { + authChecker: (_, roles) => { authCheckerRoles = roles; return true; }, @@ -464,7 +463,7 @@ describe("Authorization", () => { adminOrRegularQuery }`; - const result = await graphql(localSchema, query, null, {}); + const result: any = await graphql({ schema: localSchema, source: query, contextValue: {} }); expect(result.data!.adminOrRegularQuery).toEqual(false); expect(authCheckerRoles).toEqual(["ADMIN", "REGULAR"]); @@ -483,12 +482,12 @@ describe("Authorization", () => { adminOrRegularQuery }`; - const result = await graphql( - localSchema, - query, - { field: "rootField" }, - { field: "contextField" }, - ); + const result: any = await graphql({ + schema: localSchema, + source: query, + rootValue: { field: "rootField" }, + contextValue: { field: "contextField" }, + }); expect(result.data!.adminOrRegularQuery).toEqual(false); expect(authCheckerResolverData.root.field).toEqual("rootField"); @@ -520,16 +519,16 @@ describe("Authorization", () => { } `; - const result = await graphql( - localSchema, - query, - { field: "rootField" }, - { field: "contextField" }, - ); + const result: any = await graphql({ + schema: localSchema, + source: query, + rootValue: { field: "rootField" }, + contextValue: { field: "contextField" }, + }); expect(result.data).toBeNull(); expect(result.errors).toMatchInlineSnapshot(` - Array [ + [ [GraphQLError: Access denied! You don't have permission for this action!], ] `); @@ -562,11 +561,13 @@ describe("Authorization", () => { }); it("should not throw an error", async () => { - await buildSchema({ - resolvers: [testResolver], - // dummy auth checker - authChecker: () => false, - }); + await expect( + buildSchema({ + resolvers: [testResolver], + // dummy auth checker + authChecker: () => false, + }), + ).resolves.not.toThrow(); }); }); }); diff --git a/tests/functional/circular-refs.ts b/tests/functional/circular-refs.ts index 4eb75abc3..838196413 100644 --- a/tests/functional/circular-refs.ts +++ b/tests/functional/circular-refs.ts @@ -1,22 +1,23 @@ import "reflect-metadata"; -import { IntrospectionObjectType, TypeKind, GraphQLObjectType, graphql } from "graphql"; - -import { Query, ObjectType, Field, Resolver, buildSchema } from "../../src"; -import { getMetadataStorage } from "../../src/metadata/getMetadataStorage"; +import { type IntrospectionObjectType, TypeKind, graphql } from "graphql"; +import { Field, ObjectType, Query, Resolver, buildSchema } from "type-graphql"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { expectToThrow } from "../helpers/expectToThrow"; import { getSchemaInfo } from "../helpers/getSchemaInfo"; describe("Circular references", () => { it("should resolve circular type dependencies when type functions are used", async () => { getMetadataStorage().clear(); - const { CircularRef1 } = require("../helpers/circular-refs/good/CircularRef1"); - const { CircularRef2 } = require("../helpers/circular-refs/good/CircularRef2"); + const { CircularRef1 } = await import("../helpers/circular-refs/good/CircularRef1"); + const { CircularRef2 } = await import("../helpers/circular-refs/good/CircularRef2"); @ObjectType() class SampleObject { - @Field(type => CircularRef1) + @Field(() => CircularRef1) ref1: any; - @Field(type => CircularRef2) + + @Field(() => CircularRef2) ref2: any; } @Resolver() @@ -44,41 +45,37 @@ describe("Circular references", () => { }); it("should throw error when not providing type function for circular type references", async () => { - expect.assertions(6); getMetadataStorage().clear(); - try { - require("../helpers/circular-refs/wrong/CircularRef1").CircularRef1; - } catch (err) { - expect(err).toBeInstanceOf(Error); - const error: Error = err; - expect(error.message).toContain("provide explicit type"); - expect(error.message).toContain("ref1Field"); - jest.resetModules(); - } + const errorRef1 = await expectToThrow( + async () => (await import("../helpers/circular-refs/wrong/CircularRef1")).CircularRef1, + ); - try { - require("../helpers/circular-refs/wrong/CircularRef2").CircularRef2; - } catch (err) { - expect(err).toBeInstanceOf(Error); - const error: Error = err; - expect(error.message).toContain("provide explicit type"); - expect(error.message).toContain("ref2Field"); - jest.resetModules(); - } + expect(errorRef1).toBeInstanceOf(Error); + expect(errorRef1.message).toContain("provide explicit type"); + expect(errorRef1.message).toContain("ref1Field"); + jest.resetModules(); + + const errorRef2 = await expectToThrow( + async () => (await import("../helpers/circular-refs/wrong/CircularRef2")).CircularRef2, + ); + expect(errorRef2).toBeInstanceOf(Error); + expect(errorRef2.message).toContain("provide explicit type"); + expect(errorRef2.message).toContain("ref2Field"); + jest.resetModules(); }); it("should allow to have self-reference fields in object type", async () => { @ObjectType() class SampleObject { @Field() - stringField: string; + stringField!: string; - @Field(type => SampleObject, { nullable: true }) + @Field(() => SampleObject, { nullable: true }) selfReferenceField?: SampleObject; - @Field(type => [SampleObject]) - selfReferenceArrayField: SampleObject[]; + @Field(() => [SampleObject]) + selfReferenceArrayField!: SampleObject[]; } @Resolver() class SampleResolver { @@ -117,7 +114,7 @@ describe("Circular references", () => { } } `; - const { data } = await graphql(schema, query); + const { data } = await graphql({ schema, source: query }); expect(data!.objectQuery).toEqual({ stringField: "stringField", diff --git a/tests/functional/default-nullable.ts b/tests/functional/default-nullable.ts index 98549ec3b..b0048b789 100644 --- a/tests/functional/default-nullable.ts +++ b/tests/functional/default-nullable.ts @@ -1,15 +1,14 @@ import "reflect-metadata"; import { - IntrospectionSchema, - IntrospectionObjectType, - IntrospectionNonNullTypeRef, - IntrospectionNamedTypeRef, + type IntrospectionListTypeRef, + type IntrospectionNamedTypeRef, + type IntrospectionNonNullTypeRef, + type IntrospectionObjectType, + type IntrospectionSchema, TypeKind, - IntrospectionListTypeRef, } from "graphql"; - -import { Field, ObjectType, Resolver, Query } from "../../src"; -import { getMetadataStorage } from "../../src/metadata/getMetadataStorage"; +import { Field, ObjectType, Query, Resolver } from "type-graphql"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; import { getSchemaInfo } from "../helpers/getSchemaInfo"; describe("buildSchema -> nullableByDefault", () => { @@ -22,32 +21,32 @@ describe("buildSchema -> nullableByDefault", () => { @ObjectType() class SampleObject { @Field() - normalField: string; + normalField!: string; - @Field(type => [String]) - normalArrayField: string[]; + @Field(() => [String]) + normalArrayField!: string[]; @Field({ nullable: true }) - nullableField: string; + nullableField!: string; @Field({ nullable: false }) - nonNullableField: string; + nonNullableField!: string; } SampleObjectClass = SampleObject; - @Resolver(of => SampleObject) + @Resolver(() => SampleObject) class SampleResolver { @Query() normalQuery(): string { return "normalQuery"; } - @Query(returns => [String]) + @Query(() => [String]) normalArrayQuery(): string[] { return ["normalArrayQuery"]; } - @Query(type => String, { nullable: true }) + @Query(() => String, { nullable: true }) nullableQuery() { return null; } @@ -85,8 +84,10 @@ describe("buildSchema -> nullableByDefault", () => { const normalArrayField = sampleObjectType.fields.find(it => it.name === "normalArrayField"); const normalArrayFieldType = normalArrayField!.type as IntrospectionNonNullTypeRef; const normalArrayFieldListType = normalArrayFieldType.ofType as IntrospectionListTypeRef; - const normalArrayFieldListElementType = normalArrayFieldListType.ofType as IntrospectionNonNullTypeRef; - const normalArrayFieldListElementInnerType = normalArrayFieldListElementType.ofType as IntrospectionNamedTypeRef; + const normalArrayFieldListElementType = + normalArrayFieldListType.ofType as IntrospectionNonNullTypeRef; + const normalArrayFieldListElementInnerType = + normalArrayFieldListElementType.ofType as IntrospectionNamedTypeRef; expect(normalArrayFieldType.kind).toBe(TypeKind.NON_NULL); expect(normalArrayFieldListType.kind).toBe(TypeKind.LIST); expect(normalArrayFieldListElementType.kind).toBe(TypeKind.NON_NULL); @@ -104,8 +105,10 @@ describe("buildSchema -> nullableByDefault", () => { const normalArrayQuery = queryType.fields.find(it => it.name === "normalArrayQuery"); const normalArrayQueryType = normalArrayQuery!.type as IntrospectionNonNullTypeRef; const normalArrayQueryListType = normalArrayQueryType.ofType as IntrospectionListTypeRef; - const normalArrayQueryListElementType = normalArrayQueryListType.ofType as IntrospectionNonNullTypeRef; - const normalArrayQueryListElementInnerType = normalArrayQueryListElementType.ofType as IntrospectionNamedTypeRef; + const normalArrayQueryListElementType = + normalArrayQueryListType.ofType as IntrospectionNonNullTypeRef; + const normalArrayQueryListElementInnerType = + normalArrayQueryListElementType.ofType as IntrospectionNamedTypeRef; expect(normalArrayQueryType.kind).toBe(TypeKind.NON_NULL); expect(normalArrayQueryListType.kind).toBe(TypeKind.LIST); expect(normalArrayQueryListElementType.kind).toBe(TypeKind.NON_NULL); @@ -137,7 +140,8 @@ describe("buildSchema -> nullableByDefault", () => { const normalArrayField = sampleObjectType.fields.find(it => it.name === "normalArrayField"); const normalArrayFieldType = normalArrayField!.type as IntrospectionListTypeRef; - const normalArrayFieldListElementInnerType = normalArrayFieldType.ofType as IntrospectionNamedTypeRef; + const normalArrayFieldListElementInnerType = + normalArrayFieldType.ofType as IntrospectionNamedTypeRef; expect(normalArrayFieldType.kind).toBe(TypeKind.LIST); expect(normalArrayFieldListElementInnerType.kind).toBe(TypeKind.SCALAR); expect(normalArrayFieldListElementInnerType.name).toBe("String"); @@ -150,7 +154,8 @@ describe("buildSchema -> nullableByDefault", () => { const normalArrayQuery = queryType.fields.find(it => it.name === "normalArrayQuery"); const normalArrayQueryType = normalArrayQuery!.type as IntrospectionListTypeRef; - const normalArrayQueryListElementInnerType = normalArrayQueryType.ofType as IntrospectionNamedTypeRef; + const normalArrayQueryListElementInnerType = + normalArrayQueryType.ofType as IntrospectionNamedTypeRef; expect(normalArrayQueryType.kind).toBe(TypeKind.LIST); expect(normalArrayQueryListElementInnerType.kind).toBe(TypeKind.SCALAR); expect(normalArrayQueryListElementInnerType.name).toBe("String"); diff --git a/tests/functional/default-values.ts b/tests/functional/default-values.ts index f5b8f5e02..c94395a6f 100644 --- a/tests/functional/default-values.ts +++ b/tests/functional/default-values.ts @@ -1,16 +1,15 @@ import "reflect-metadata"; -import { GraphQLSchema, printType } from "graphql"; +import { type GraphQLSchema, printType } from "graphql"; import { Arg, - buildSchema, - ClassType, + type ClassType, Field, - getMetadataStorage, InputType, Query, Resolver, -} from "../../src"; - + buildSchema, + getMetadataStorage, +} from "type-graphql"; import { getSchemaInfo } from "../helpers/getSchemaInfo"; describe("default values", () => { @@ -40,7 +39,7 @@ describe("default values", () => { }); it("should not throw error when schema with dynamic default has been built again", async () => { - await expect(buildSchema({ resolvers: [sampleResolver] })).resolves.not.toThrowError(); + await expect(buildSchema({ resolvers: [sampleResolver] })).resolves.not.toThrow(); }); }); @@ -58,7 +57,7 @@ describe("default values", () => { @InputType() class SampleOptionInput { @Field({ defaultValue: "defaultValueFromOption" }) - inputField: string; + inputField!: string; } @Resolver() @@ -88,13 +87,13 @@ describe("default values", () => { `); }); - it("should not infer default value from a property initializer", async () => { + it("should read default value from a decorator option", async () => { const sampleOptionInputType = schema.getType("SampleOptionInput")!; const sampleOptionInputSDL = printType(sampleOptionInputType); expect(sampleOptionInputSDL).toMatchInlineSnapshot(` "input SampleOptionInput { - inputField: String! = \\"defaultValueFromOption\\" + inputField: String! = "defaultValueFromOption" }" `); }); @@ -109,13 +108,13 @@ describe("default values", () => { @InputType() class SampleInput { @Field({ defaultValue: "stringDefaultValue", nullable: false }) - inputField: string; + inputField!: string; } @Resolver() class SampleResolver { @Query() - sampleQuery(@Arg("input") input: SampleInput): string { + sampleQuery(@Arg("input") _input: SampleInput): string { return "sampleQuery"; } } @@ -128,7 +127,7 @@ describe("default values", () => { expect(sampleInputSDL).toMatchInlineSnapshot(` "input SampleInput { - inputField: String! = \\"stringDefaultValue\\" + inputField: String! = "stringDefaultValue" }" `); }); @@ -142,7 +141,7 @@ describe("default values", () => { @InputType() class SampleInput { @Field({ defaultValue: "stringDefaultValue", nullable: true }) - inputField: string; + inputField!: string; } @Resolver() @@ -161,7 +160,7 @@ describe("default values", () => { expect(sampleInputSDL).toMatchInlineSnapshot(` "input SampleInput { - inputField: String = \\"stringDefaultValue\\" + inputField: String = "stringDefaultValue" }" `); }); @@ -176,7 +175,7 @@ describe("default values", () => { @InputType() class SampleInput { @Field({ defaultValue: "stringDefaultValue" }) - inputField: string; + inputField!: string; } @Resolver() @@ -198,7 +197,7 @@ describe("default values", () => { expect(sampleInputSDL).toMatchInlineSnapshot(` "input SampleInput { - inputField: String = \\"stringDefaultValue\\" + inputField: String = "stringDefaultValue" }" `); }); @@ -212,7 +211,7 @@ describe("default values", () => { @InputType() class SampleInput { @Field({ defaultValue: "stringDefaultValue", nullable: false }) - inputField: string; + inputField!: string; } @Resolver() @@ -234,7 +233,7 @@ describe("default values", () => { expect(sampleInputSDL).toMatchInlineSnapshot(` "input SampleInput { - inputField: String! = \\"stringDefaultValue\\" + inputField: String! = "stringDefaultValue" }" `); }); diff --git a/tests/functional/deprecation.ts b/tests/functional/deprecation.ts index ea56dab68..c095aec71 100644 --- a/tests/functional/deprecation.ts +++ b/tests/functional/deprecation.ts @@ -1,17 +1,21 @@ import "reflect-metadata"; -import { IntrospectionSchema, IntrospectionObjectType, GraphQLSchema, printType } from "graphql"; - import { - ObjectType, - Resolver, - Field, - Query, - Mutation, - InputType, + type GraphQLSchema, + type IntrospectionObjectType, + type IntrospectionSchema, + printType, +} from "graphql"; +import { Arg, - ArgsType, Args, -} from "../../src"; + ArgsType, + Field, + InputType, + Mutation, + ObjectType, + Query, + Resolver, +} from "type-graphql"; import { getSchemaInfo } from "../helpers/getSchemaInfo"; describe("Deprecation", () => { @@ -22,17 +26,18 @@ describe("Deprecation", () => { let queryType: IntrospectionObjectType; beforeAll(async () => { - // create sample definitions + // Create sample definitions @ObjectType() class SampleObject { @Field() - normalField: string; + normalField!: string; @Field({ deprecationReason: "sample object field deprecation reason" }) - deprecatedField: string; + deprecatedField!: string; @Field({ deprecationReason: "sample object getter field deprecation reason" }) + // eslint-disable-next-line @typescript-eslint/class-literal-property-style get deprecatedGetterField(): string { return "deprecatedGetterField"; } @@ -46,28 +51,28 @@ describe("Deprecation", () => { @InputType() class SampleInput { @Field() - normalField: string; + normalField!: string; @Field({ deprecationReason: "sample input field deprecation reason", nullable: true, }) - deprecatedField: string; + deprecatedField!: string; } @ArgsType() class SampleArgs { @Field() - normalArg: string; + normalArg!: string; @Field({ deprecationReason: "sample args field deprecation reason", nullable: true, }) - deprecatedArg: string; + deprecatedArg!: string; } - @Resolver(of => SampleObject) + @Resolver(() => SampleObject) class SampleResolver { @Query() normalQuery(): SampleObject { @@ -75,12 +80,12 @@ describe("Deprecation", () => { } @Query() - inputQuery(@Arg("input") input: SampleInput): SampleObject { + inputQuery(@Arg("input") _input: SampleInput): SampleObject { return {} as SampleObject; } @Query() - argsQuery(@Args() args: SampleArgs): SampleObject { + argsQuery(@Args() _args: SampleArgs): SampleObject { return {} as SampleObject; } @@ -90,7 +95,7 @@ describe("Deprecation", () => { deprecationReason: "sample query arg deprecation reason", nullable: true, }) - arg?: string, + _arg?: string, ): SampleObject { return {} as SampleObject; } @@ -155,7 +160,7 @@ describe("Deprecation", () => { expect(sampleInputTypeSDL).toMatchInlineSnapshot(` "input SampleInput { normalField: String! - deprecatedField: String @deprecated(reason: \\"sample input field deprecation reason\\") + deprecatedField: String @deprecated(reason: "sample input field deprecation reason") }" `); }); diff --git a/tests/functional/description.ts b/tests/functional/description.ts index a0210a945..6adc0ca2e 100644 --- a/tests/functional/description.ts +++ b/tests/functional/description.ts @@ -1,21 +1,20 @@ import "reflect-metadata"; import { - IntrospectionSchema, - IntrospectionObjectType, - IntrospectionInputObjectType, + type IntrospectionInputObjectType, + type IntrospectionObjectType, + type IntrospectionSchema, } from "graphql"; - import { - ObjectType, + Arg, + Args, ArgsType, - InputType, - Resolver, Field, - Query, + InputType, Mutation, - Arg, - Args, -} from "../../src"; + ObjectType, + Query, + Resolver, +} from "type-graphql"; import { getSchemaInfo } from "../helpers/getSchemaInfo"; describe("Description", () => { @@ -25,24 +24,25 @@ describe("Description", () => { let queryType: IntrospectionObjectType; beforeAll(async () => { - // create sample definitions + // Create sample definitions @ObjectType({ description: "sample object description" }) class SampleObject { @Field() - normalField: string; + normalField!: string; @Field({ description: "sample object field description" }) - describedField: string; + describedField!: string; @Field({ description: "sample object getter field description" }) + // eslint-disable-next-line @typescript-eslint/class-literal-property-style get describedGetterField(): string { return "describedGetterField"; } @Field({ description: "sample object method field description" }) methodField( - @Arg("arg", { description: "sample object method arg description" }) arg: string, + @Arg("arg", { description: "sample object method arg description" }) _arg: string, ): string { return "methodField"; } @@ -51,22 +51,22 @@ describe("Description", () => { @InputType({ description: "sample input description" }) class SampleInput { @Field() - normalField: string; + normalField!: string; @Field({ description: "sample input field description" }) - describedField: string; + describedField!: string; } @ArgsType() class SampleArguments { @Field() - normalField: string; + normalField!: string; @Field({ description: "sample argument field description" }) - describedField: string; + describedField!: string; } - @Resolver(of => SampleObject) + @Resolver(() => SampleObject) class SampleResolver { @Query() normalQuery(): string { @@ -75,20 +75,20 @@ describe("Description", () => { @Query({ description: "sample query description" }) describedQuery( - @Arg("normalArg") normalArg: string, + @Arg("normalArg") _normalArg: string, @Arg("describedArg", { description: "sample query arg description" }) - describedArg: string, + _describedArg: string, ): string { return "describedQuery"; } @Query() - argumentedQuery(@Args() args: SampleArguments): string { + argumentedQuery(@Args() _args: SampleArguments): string { return "argumentedQuery"; } @Query() - inputQuery(@Arg("input") input: SampleInput): string { + inputQuery(@Arg("input") _input: SampleInput): string { return "inputQuery"; } @@ -99,25 +99,25 @@ describe("Description", () => { @Mutation({ description: "sample mutation description" }) describedMutation( - @Arg("normalArg") normalArg: string, + @Arg("normalArg") _normalArg: string, @Arg("describedArg", { description: "sample mutation arg description" }) - describedArg: string, + _describedArg: string, ): string { return "describedMutation"; } @Mutation() - argumentedMutation(@Args() args: SampleArguments): string { + argumentedMutation(@Args() _args: SampleArguments): string { return "argumentedMutation"; } @Mutation() - inputMutation(@Arg("input") input: SampleInput): string { + inputMutation(@Arg("input") _input: SampleInput): string { return "inputMutation"; } } - // get builded schema info from retrospection + // Get builded schema info from retrospection const schemaInfo = await getSchemaInfo({ resolvers: [SampleResolver], orphanedTypes: [SampleObject], diff --git a/tests/functional/directives.ts b/tests/functional/directives.ts index 75ed4fbb5..1b6e536b2 100644 --- a/tests/functional/directives.ts +++ b/tests/functional/directives.ts @@ -1,541 +1,678 @@ -// tslint:disable:member-ordering import "reflect-metadata"; +import { createPubSub } from "@graphql-yoga/subscription"; import { - GraphQLSchema, - graphql, - GraphQLInputObjectType, - GraphQLInterfaceType, - GraphQLObjectType, + type GraphQLInputObjectType, + type GraphQLInterfaceType, + type GraphQLObjectType, + type GraphQLSchema, + OperationTypeNode, } from "graphql"; import { - Field, - InputType, - Resolver, - Query, Arg, + Args, + ArgsType, Directive, - buildSchema, - ObjectType, + Field, + InputType, + InterfaceType, Mutation, - FieldResolver, + ObjectType, + Query, + Resolver, Subscription, - InterfaceType, -} from "../../src"; -import { getMetadataStorage } from "../../src/metadata/getMetadataStorage"; -import { SchemaDirectiveVisitor } from "graphql-tools"; -import { UpperCaseDirective } from "../helpers/directives/UpperCaseDirective"; -import { AppendDirective } from "../helpers/directives/AppendDirective"; + buildSchema, +} from "type-graphql"; +import { InvalidDirectiveError } from "@/errors/InvalidDirectiveError"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; import { assertValidDirective } from "../helpers/directives/assertValidDirective"; -import { InvalidDirectiveError } from "../../src/errors/InvalidDirectiveError"; +import { testDirective, testDirectiveTransformer } from "../helpers/directives/TestDirective"; +import { expectToThrow } from "../helpers/expectToThrow"; describe("Directives", () => { - let schema: GraphQLSchema; - describe("Schema", () => { - beforeAll(async () => { + beforeEach(async () => { getMetadataStorage().clear(); + }); - @InputType() - class DirectiveOnFieldInput { - @Field() - @Directive("@upper") - append: string; - } + describe("on ObjectType", () => { + let schema: GraphQLSchema; + beforeAll(async () => { + @Directive("@test") + @ObjectType() + class SampleObject { + @Field() + sampleField!: string; + } + @Resolver() + class SampleResolver { + @Query() + sampleQuery(): SampleObject { + return { sampleField: "sampleField" }; + } + } - @InputType() - class SubDirectiveOnFieldInput extends DirectiveOnFieldInput {} + schema = await buildSchema({ + resolvers: [SampleResolver], + directives: [testDirective], + validate: false, + }); + schema = testDirectiveTransformer(schema); + }); - @InputType() - @Directive("@upper") - class DirectiveOnClassInput { - @Field() - append: string; - } + it("should properly emit directive in AST", () => { + const sampleObjectTypeInfo = schema.getType("SampleObject") as GraphQLObjectType; - @ObjectType() - class SampleObjectType { - @Field() - @Directive("foo") - withDirective: string = "withDirective"; + expect(() => { + assertValidDirective(sampleObjectTypeInfo.astNode, "test"); + }).not.toThrow(); + }); - // @Field() - // @Directive("bar", { baz: "true" }) - // withDirectiveWithArgs: string = "withDirectiveWithArgs"; + it("should properly apply directive mapper", async () => { + const sampleObjectTypeInfo = schema.getType("SampleObject") as GraphQLObjectType; - @Field() - @Directive("upper") - withUpper: string = "withUpper"; + expect(sampleObjectTypeInfo.extensions).toMatchObject({ + TypeGraphQL: { isMappedByDirective: true }, + }); + }); + }); - @Field() - @Directive("@upper") - withUpperDefinition: string = "withUpperDefinition"; + describe("on ObjectType field", () => { + let schema: GraphQLSchema; + beforeAll(async () => { + @ObjectType() + class SampleObject { + @Field() + @Directive("@test") + sampleField!: string; + } + @Resolver() + class SampleResolver { + @Query() + sampleQuery(): SampleObject { + return { sampleField: "sampleField" }; + } + } - @Field() - @Directive("append") - withAppend: string = "hello"; + schema = await buildSchema({ + resolvers: [SampleResolver], + directives: [testDirective], + validate: false, + }); + schema = testDirectiveTransformer(schema); + }); - @Field() - @Directive("@append") - withAppendDefinition: string = "hello"; + it("should properly emit directive in AST", () => { + const sampleFieldTypeInfo = ( + schema.getType("SampleObject") as GraphQLObjectType + ).getFields().sampleField; - @Field() - @Directive("append") - @Directive("upper") - withUpperAndAppend: string = "hello"; + expect(() => { + assertValidDirective(sampleFieldTypeInfo.astNode, "test"); + }).not.toThrow(); + }); - @Field() - withInput(@Arg("input") input: DirectiveOnFieldInput): string { - return `hello${input.append}`; - } + it("should properly apply directive mapper", async () => { + const sampleFieldTypeInfo = ( + schema.getType("SampleObject") as GraphQLObjectType + ).getFields().sampleField; - @Field() - @Directive("upper") - withInputUpper(@Arg("input") input: DirectiveOnFieldInput): string { - return `hello${input.append}`; - } + expect(sampleFieldTypeInfo.extensions).toMatchObject({ + TypeGraphQL: { isMappedByDirective: true }, + }); + }); + }); - @Field() - withInputOnClass(@Arg("input") input: DirectiveOnClassInput): string { - return `hello${input.append}`; + describe("on ObjectType field argument", () => { + let schema: GraphQLSchema; + beforeAll(async () => { + @ArgsType() + class SampleArgs { + @Directive("@test") + @Field() + sampleArgument!: string; } - - @Field() - @Directive("upper") - withInputUpperOnClass(@Arg("input") input: DirectiveOnClassInput): string { - return `hello${input.append}`; + @ObjectType() + class SampleObject { + @Field() + sampleField(@Args() { sampleArgument }: SampleArgs): string { + return sampleArgument; + } } - } - - @ObjectType() - class SubSampleObjectType extends SampleObjectType { - @Field() - withInput(@Arg("input") input: SubDirectiveOnFieldInput): string { - return `hello${input.append}`; + @Resolver() + class SampleResolver { + @Query() + sampleQuery(): SampleObject { + return new SampleObject(); + } } - } - @InterfaceType() - @Directive("foo") - abstract class DirectiveOnInterface { - @Field() - @Directive("bar") - withDirective: string; - } + schema = await buildSchema({ + resolvers: [SampleResolver], + directives: [testDirective], + validate: false, + }); + schema = testDirectiveTransformer(schema); + }); - @ObjectType({ implements: DirectiveOnInterface }) - class ObjectImplement extends DirectiveOnInterface {} + it("should properly emit directive in AST", () => { + const sampleFieldArgTypeInfo = ( + schema.getType("SampleObject") as GraphQLObjectType + ).getFields().sampleField.args[0]; - @Resolver() - class SampleResolver { - @Query(() => SampleObjectType) - objectType(): SampleObjectType { - return new SampleObjectType(); - } + expect(() => { + assertValidDirective(sampleFieldArgTypeInfo.astNode, "test"); + }).not.toThrow(); + }); - @Query() - @Directive("foo") - queryWithDirective(): string { - return "queryWithDirective"; - } + it("should properly apply directive mapper", async () => { + const sampleFieldArgTypeInfo = ( + schema.getType("SampleObject") as GraphQLObjectType + ).getFields().sampleField.args[0]; - // @Query() - // @Directive("bar", { baz: "true" }) - // queryWithDirectiveWithArgs(): string { - // return "queryWithDirectiveWithArgs"; - // } + expect(sampleFieldArgTypeInfo.extensions).toMatchObject({ + TypeGraphQL: { isMappedByDirective: true }, + }); + }); + }); - @Query() - @Directive("upper") - queryWithUpper(): string { - return "queryWithUpper"; + describe("on InterfaceType", () => { + let schema: GraphQLSchema; + beforeAll(async () => { + @Directive("@test") + @InterfaceType() + class SampleInterface { + @Field() + sampleField!: string; } - - @Query() - @Directive("@upper") - queryWithUpperDefinition(): string { - return "queryWithUpper"; + @ObjectType({ implements: [SampleInterface] }) + class SampleObject extends SampleInterface {} + @Resolver() + class SampleResolver { + @Query() + sampleQuery(): SampleInterface { + const sampleObject = new SampleObject(); + sampleObject.sampleField = "sampleField"; + return sampleObject; + } } - @Query() - @Directive("append") - queryWithAppend(): string { - return "hello"; - } + schema = await buildSchema({ + resolvers: [SampleResolver], + orphanedTypes: [SampleObject], + directives: [testDirective], + validate: false, + }); + schema = testDirectiveTransformer(schema); + }); - @Query() - @Directive("@append") - queryWithAppendDefinition(): string { - return "hello"; - } + it("should properly emit directive in AST", () => { + const sampleInterfaceTypeInfo = schema.getType("SampleInterface") as GraphQLInterfaceType; - @Query() - @Directive("append") - @Directive("upper") - queryWithUpperAndAppend(): string { - return "hello"; - } + expect(() => { + assertValidDirective(sampleInterfaceTypeInfo.astNode, "test"); + }).not.toThrow(); + }); - @Mutation() - @Directive("foo") - mutationWithDirective(): string { - return "mutationWithDirective"; - } + it("should properly apply directive mapper", async () => { + const sampleInterfaceTypeInfo = schema.getType("SampleInterface") as GraphQLInterfaceType; - // @Mutation() - // @Directive("bar", { baz: "true" }) - // mutationWithDirectiveWithArgs(): string { - // return "mutationWithDirectiveWithArgs"; - // } + expect(sampleInterfaceTypeInfo.extensions).toMatchObject({ + TypeGraphQL: { isMappedByDirective: true }, + }); + }); + }); - @Mutation() - @Directive("upper") - mutationWithUpper(): string { - return "mutationWithUpper"; + describe("on InterfaceType field", () => { + let schema: GraphQLSchema; + beforeAll(async () => { + @InterfaceType() + class SampleInterface { + @Directive("@test") + @Field() + sampleField!: string; } - - @Mutation() - @Directive("@upper") - mutationWithUpperDefinition(): string { - return "mutationWithUpper"; + @ObjectType({ implements: [SampleInterface] }) + class SampleObject extends SampleInterface {} + @Resolver() + class SampleResolver { + @Query() + sampleQuery(): SampleInterface { + const sampleObject = new SampleObject(); + sampleObject.sampleField = "sampleField"; + return sampleObject; + } } - @Mutation() - @Directive("append") - mutationWithAppend(): string { - return "hello"; - } + schema = await buildSchema({ + resolvers: [SampleResolver], + orphanedTypes: [SampleObject], + directives: [testDirective], + validate: false, + }); + schema = testDirectiveTransformer(schema); + }); - @Mutation() - @Directive("@append") - mutationWithAppendDefinition(): string { - return "hello"; - } + it("should properly emit directive in AST", () => { + const sampleFieldTypeInfo = ( + schema.getType("SampleInterface") as GraphQLInterfaceType + ).getFields().sampleField; - @Mutation() - @Directive("append") - @Directive("upper") - mutationWithUpperAndAppend(): string { - return "hello"; - } + expect(() => { + assertValidDirective(sampleFieldTypeInfo.astNode, "test"); + }).not.toThrow(); + }); - @Subscription({ topics: "TEST" }) - @Directive("@foo") - subscriptionWithDirective(): string { - return "subscriptionWithDirective"; - } - } + it("should properly apply directive mapper", async () => { + const sampleFieldTypeInfo = ( + schema.getType("SampleInterface") as GraphQLInterfaceType + ).getFields().sampleField; - @Resolver(of => SampleObjectType) - class SampleObjectTypeResolver { - @FieldResolver() - @Directive("@append") - fieldResolverWithAppendDefinition(): string { - return "hello"; - } - } + expect(sampleFieldTypeInfo.extensions).toMatchObject({ + TypeGraphQL: { isMappedByDirective: true }, + }); + }); + }); - @Resolver(of => SubSampleObjectType) - class SubSampleResolver { - @Query(() => SubSampleObjectType) - subObjectType(): SubSampleObjectType { - return new SubSampleObjectType(); + describe("on InputType", () => { + let schema: GraphQLSchema; + beforeAll(async () => { + @Directive("@test") + @InputType() + class SampleInput { + @Field() + sampleField!: string; } - } - - @Resolver(() => ObjectImplement) - class ObjectImplementResolver { - @Query(() => ObjectImplement) - objectImplentingInterface(): ObjectImplement { - return new ObjectImplement(); + @Resolver() + class SampleResolver { + @Query() + sampleQuery(@Arg("input") _input: SampleInput): boolean { + return true; + } } - } - schema = await buildSchema({ - resolvers: [ - SampleResolver, - SampleObjectTypeResolver, - SubSampleResolver, - ObjectImplementResolver, - ], - validate: false, + schema = await buildSchema({ + resolvers: [SampleResolver], + directives: [testDirective], + validate: false, + }); + schema = testDirectiveTransformer(schema); }); - SchemaDirectiveVisitor.visitSchemaDirectives(schema, { - upper: UpperCaseDirective, - append: AppendDirective, - }); - }); + it("should properly emit directive in AST", () => { + const sampleInputTypeInfo = schema.getType("SampleInput") as GraphQLInputObjectType; - it("should generate schema without errors", async () => { - expect(schema).toBeDefined(); - }); + expect(() => { + assertValidDirective(sampleInputTypeInfo.astNode, "test"); + }).not.toThrow(); + }); - describe("Query", () => { - it("should add directives to query types", async () => { - const queryWithDirective = schema.getQueryType()!.getFields().queryWithDirective; + it("should properly apply directive mapper", async () => { + const sampleInputTypeInfo = schema.getType("SampleInput") as GraphQLInputObjectType; - assertValidDirective(queryWithDirective.astNode, "foo"); + expect(sampleInputTypeInfo.extensions).toMatchObject({ + TypeGraphQL: { isMappedByDirective: true }, + }); }); + }); - // it("should add directives to query types with arguments", async () => { - // const queryWithDirectiveWithArgs = schema.getQueryType()!.getFields() - // .queryWithDirectiveWithArgs; - - // assertValidDirective(queryWithDirectiveWithArgs.astNode, "bar", { baz: "true" }); - // }); + describe("on InputType field", () => { + let schema: GraphQLSchema; + beforeAll(async () => { + @InputType() + class SampleInput { + @Field() + @Directive("@test") + sampleField!: string; + } + @Resolver() + class SampleResolver { + @Query() + sampleQuery(@Arg("input") _input: SampleInput): boolean { + return true; + } + } - it("calls directive 'upper'", async () => { - const query = `query { - queryWithUpper - }`; + schema = await buildSchema({ + resolvers: [SampleResolver], + directives: [testDirective], + validate: false, + }); + schema = testDirectiveTransformer(schema); + }); - const { data } = await graphql(schema, query); + it("should properly emit directive in AST", () => { + const sampleFieldTypeInfo = ( + schema.getType("SampleInput") as GraphQLInputObjectType + ).getFields().sampleField; - expect(data).toHaveProperty("queryWithUpper", "QUERYWITHUPPER"); + expect(() => { + assertValidDirective(sampleFieldTypeInfo.astNode, "test"); + }).not.toThrow(); }); - it("calls directive 'upper' using Definition", async () => { - const query = `query { - queryWithUpperDefinition - }`; - - const { data } = await graphql(schema, query); + it("should properly apply directive mapper", async () => { + const sampleFieldTypeInfo = ( + schema.getType("SampleInput") as GraphQLInputObjectType + ).getFields().sampleField; - expect(data).toHaveProperty("queryWithUpperDefinition", "QUERYWITHUPPER"); + expect(sampleFieldTypeInfo.extensions).toMatchObject({ + TypeGraphQL: { isMappedByDirective: true }, + }); }); + }); - it("calls directive 'append'", async () => { - const query = `query { - queryWithAppend(append: ", world!") - }`; - - const { data } = await graphql(schema, query); + describe("on Query", () => { + let schema: GraphQLSchema; + beforeAll(async () => { + @Resolver() + class SampleResolver { + @Directive("@test") + @Query() + sampleQuery(): boolean { + return true; + } + } - expect(data).toHaveProperty("queryWithAppend", "hello, world!"); + schema = await buildSchema({ + resolvers: [SampleResolver], + directives: [testDirective], + validate: false, + }); + schema = testDirectiveTransformer(schema); }); - it("calls directive 'append' using Definition", async () => { - const query = `query { - queryWithAppendDefinition(append: ", world!") - }`; + it("should properly emit directive in AST", () => { + const sampleQueryInfo = schema + .getRootType(OperationTypeNode.QUERY)! + .getFields().sampleQuery; - const { data } = await graphql(schema, query); - - expect(data).toHaveProperty("queryWithAppendDefinition", "hello, world!"); + expect(() => { + assertValidDirective(sampleQueryInfo.astNode, "test"); + }).not.toThrow(); }); - it("calls directive 'upper' and 'append'", async () => { - const query = `query { - queryWithUpperAndAppend(append: ", world!") - }`; - - const { data } = await graphql(schema, query); + it("should properly apply directive mapper", async () => { + const sampleQueryInfo = schema + .getRootType(OperationTypeNode.QUERY)! + .getFields().sampleQuery; - expect(data).toHaveProperty("queryWithUpperAndAppend", "HELLO, WORLD!"); + expect(sampleQueryInfo.extensions).toMatchObject({ + TypeGraphQL: { isMappedByDirective: true }, + }); }); }); - describe("Mutation", () => { - it("should add directives to mutation types", async () => { - const mutationWithDirective = schema.getMutationType()!.getFields().mutationWithDirective; + describe("on Query field argument using @Args", () => { + let schema: GraphQLSchema; + beforeAll(async () => { + @ArgsType() + class SampleArgs { + @Directive("@test") + @Field() + sampleArgument!: string; + } + @Resolver() + class SampleResolver { + @Query() + sampleQuery(@Args() { sampleArgument }: SampleArgs): string { + return sampleArgument; + } + } - assertValidDirective(mutationWithDirective.astNode, "foo"); + schema = await buildSchema({ + resolvers: [SampleResolver], + directives: [testDirective], + validate: false, + }); + schema = testDirectiveTransformer(schema); }); - // it("should add directives to mutation types with arguments", async () => { - // const mutationWithDirectiveWithArgs = schema.getMutationType()!.getFields() - // .mutationWithDirectiveWithArgs; - - // assertValidDirective(mutationWithDirectiveWithArgs.astNode, "bar", { baz: "true" }); - // }); - - it("calls directive 'upper'", async () => { - const mutation = `mutation { - mutationWithUpper - }`; + it("should properly emit directive in AST", () => { + const sampleQueryArgTypeInfo = (schema.getType("Query") as GraphQLObjectType).getFields() + .sampleQuery.args[0]; - const { data } = await graphql(schema, mutation); - - expect(data).toHaveProperty("mutationWithUpper", "MUTATIONWITHUPPER"); + expect(() => { + assertValidDirective(sampleQueryArgTypeInfo.astNode, "test"); + }).not.toThrow(); }); - it("calls directive 'upper' using Definition", async () => { - const mutation = `mutation { - mutationWithUpperDefinition - }`; - - const { data } = await graphql(schema, mutation); + it("should properly apply directive mapper", async () => { + const sampleQueryArgTypeInfo = (schema.getType("Query") as GraphQLObjectType).getFields() + .sampleQuery.args[0]; - expect(data).toHaveProperty("mutationWithUpperDefinition", "MUTATIONWITHUPPER"); + expect(sampleQueryArgTypeInfo.extensions).toMatchObject({ + TypeGraphQL: { isMappedByDirective: true }, + }); }); + }); - it("calls directive 'append'", async () => { - const mutation = `mutation { - mutationWithAppend(append: ", world!") - }`; - - const { data } = await graphql(schema, mutation); + describe("on Query field argument using @Arg", () => { + let schema: GraphQLSchema; + beforeAll(async () => { + @Resolver() + class SampleResolver { + @Query() + sampleQuery( + @Arg("sampleArgument") + @Directive("@test") + sampleArgument: string, + ): string { + return sampleArgument; + } + } - expect(data).toHaveProperty("mutationWithAppend", "hello, world!"); + schema = await buildSchema({ + resolvers: [SampleResolver], + directives: [testDirective], + validate: false, + }); + schema = testDirectiveTransformer(schema); }); - it("calls directive 'append' using Definition", async () => { - const mutation = `mutation { - mutationWithAppendDefinition(append: ", world!") - }`; - - const { data } = await graphql(schema, mutation); + it("should properly emit directive in AST", () => { + const sampleQueryArgTypeInfo = (schema.getType("Query") as GraphQLObjectType).getFields() + .sampleQuery.args[0]; - expect(data).toHaveProperty("mutationWithAppendDefinition", "hello, world!"); + expect(() => { + assertValidDirective(sampleQueryArgTypeInfo.astNode, "test"); + }).not.toThrow(); }); - it("calls directive 'upper' and 'append'", async () => { - const mutation = `mutation { - mutationWithUpperAndAppend(append: ", world!") - }`; + it("should properly apply directive mapper", async () => { + const sampleQueryArgTypeInfo = (schema.getType("Query") as GraphQLObjectType).getFields() + .sampleQuery.args[0]; - const { data } = await graphql(schema, mutation); - - expect(data).toHaveProperty("mutationWithUpperAndAppend", "HELLO, WORLD!"); + expect(sampleQueryArgTypeInfo.extensions).toMatchObject({ + TypeGraphQL: { isMappedByDirective: true }, + }); }); }); - describe("Subscription", () => { - it("should add directives to subscription types", async () => { - const subscriptionWithDirective = schema.getSubscriptionType()!.getFields() - .subscriptionWithDirective; - - assertValidDirective(subscriptionWithDirective.astNode, "foo"); - }); - }); + describe("on Mutation", () => { + let schema: GraphQLSchema; + beforeAll(async () => { + @Resolver() + class SampleResolver { + @Query() + sampleQuery(): boolean { + return true; + } - describe("InputType", () => { - it("adds field directive to input types", async () => { - const inputType = schema.getType("DirectiveOnClassInput") as GraphQLInputObjectType; + @Directive("@test") + @Mutation() + sampleMutation(): boolean { + return true; + } + } - expect(inputType).toHaveProperty("astNode"); - assertValidDirective(inputType.astNode, "upper"); + schema = await buildSchema({ + resolvers: [SampleResolver], + directives: [testDirective], + validate: false, + }); + schema = testDirectiveTransformer(schema); }); - it("adds field directives to input type fields", async () => { - const fields = (schema.getType( - "DirectiveOnFieldInput", - ) as GraphQLInputObjectType).getFields(); + it("should properly emit directive in AST", () => { + const sampleMutationInfo = schema + .getRootType(OperationTypeNode.MUTATION)! + .getFields().sampleMutation; - expect(fields).toHaveProperty("append"); - expect(fields.append).toHaveProperty("astNode"); - assertValidDirective(fields.append.astNode, "upper"); + expect(() => { + assertValidDirective(sampleMutationInfo.astNode, "test"); + }).not.toThrow(); }); - it("adds inherited field directives to input type fields while extending input type class", async () => { - const fields = (schema.getType( - "SubDirectiveOnFieldInput", - ) as GraphQLInputObjectType).getFields(); + it("should properly apply directive mapper", async () => { + const sampleMutationInfo = schema + .getRootType(OperationTypeNode.MUTATION)! + .getFields().sampleMutation; - expect(fields).toHaveProperty("append"); - expect(fields.append).toHaveProperty("astNode"); - assertValidDirective(fields.append.astNode, "upper"); + expect(sampleMutationInfo.extensions).toMatchObject({ + TypeGraphQL: { isMappedByDirective: true }, + }); }); }); - describe("ObjectType", () => { - it("calls object type directives", async () => { - const query = `query { - objectType { - withDirective - # withDirectiveWithArgs - withUpper - withUpperDefinition - withAppend(append: ", world!") - withAppendDefinition(append: ", world!") - withUpperAndAppend(append: ", world!") - withInput(input: { append: ", world!" }) - withInputUpper(input: { append: ", world!" }) - withInputOnClass(input: { append: ", world!" }) - withInputUpperOnClass(input: { append: ", world!" }) - fieldResolverWithAppendDefinition(append: ", world!") + describe("on Subscription", () => { + let schema: GraphQLSchema; + beforeAll(async () => { + @Resolver() + class SampleResolver { + @Query() + sampleQuery(): boolean { + return true; + } + + @Directive("@test") + @Subscription({ topics: "sample" }) + sampleSubscription(): boolean { + return true; } - }`; - - const { data } = await graphql(schema, query); - - expect(data).toHaveProperty("objectType"); - expect(data!.objectType).toEqual({ - withDirective: "withDirective", - // withDirectiveWithArgs: "withDirectiveWithArgs", - withUpper: "WITHUPPER", - withUpperDefinition: "WITHUPPERDEFINITION", - withAppend: "hello, world!", - withAppendDefinition: "hello, world!", - withUpperAndAppend: "HELLO, WORLD!", - withInput: "hello, WORLD!", - withInputUpper: "HELLO, WORLD!", - withInputOnClass: "hello, WORLD!", - withInputUpperOnClass: "HELLO, WORLD!", - fieldResolverWithAppendDefinition: "hello, world!", + } + + schema = await buildSchema({ + resolvers: [SampleResolver], + directives: [testDirective], + validate: false, + pubSub: createPubSub(), }); + schema = testDirectiveTransformer(schema); }); - it("call object type directives while extending field type class", async () => { - const query = `query { - subObjectType { - withDirective - # withDirectiveWithArgs - withUpper - withUpperDefinition - withAppend(append: ", world!") - withAppendDefinition(append: ", world!") - withUpperAndAppend(append: ", world!") - withInput(input: { append: ", world!" }) - withInputUpper(input: { append: ", world!" }) - withInputOnClass(input: { append: ", world!" }) - withInputUpperOnClass(input: { append: ", world!" }) - fieldResolverWithAppendDefinition(append: ", world!") - } - }`; - - const { data } = await graphql(schema, query); - - expect(data).toHaveProperty("subObjectType"); - expect(data!.subObjectType).toEqual({ - withDirective: "withDirective", - // withDirectiveWithArgs: "withDirectiveWithArgs", - withUpper: "WITHUPPER", - withUpperDefinition: "WITHUPPERDEFINITION", - withAppend: "hello, world!", - withAppendDefinition: "hello, world!", - withUpperAndAppend: "HELLO, WORLD!", - withInput: "hello, WORLD!", - withInputUpper: "HELLO, WORLD!", - withInputOnClass: "hello, WORLD!", - withInputUpperOnClass: "HELLO, WORLD!", - fieldResolverWithAppendDefinition: "hello, world!", + it("should properly emit directive in AST", () => { + const sampleSubscriptionInfo = schema + .getRootType(OperationTypeNode.SUBSCRIPTION)! + .getFields().sampleSubscription; + + expect(() => { + assertValidDirective(sampleSubscriptionInfo.astNode, "test"); + }).not.toThrow(); + }); + + it("should properly apply directive mapper", async () => { + const sampleSubscriptionInfo = schema + .getRootType(OperationTypeNode.SUBSCRIPTION)! + .getFields().sampleSubscription; + + expect(sampleSubscriptionInfo.extensions).toMatchObject({ + TypeGraphQL: { isMappedByDirective: true }, }); }); }); + }); - describe("Interface", () => { - it("adds directive to interface", () => { - const interfaceType = schema.getType("DirectiveOnInterface") as GraphQLInterfaceType; + describe("multiline and leading white spaces", () => { + let schema: GraphQLSchema; + beforeAll(async () => { + @Resolver() + class SampleResolver { + @Directive("\n@test") + @Query() + multiline(): boolean { + return true; + } - expect(interfaceType).toHaveProperty("astNode"); - assertValidDirective(interfaceType.astNode, "foo"); - }); + @Directive(" @test") + @Query() + leadingWhiteSpaces(): boolean { + return true; + } - it("adds field directives to interface fields", async () => { - const fields = (schema.getType("DirectiveOnInterface") as GraphQLInterfaceType).getFields(); + @Directive("\n @test") + @Query() + multilineAndLeadingWhiteSpaces(): boolean { + return true; + } + + @Directive(` + @test( + argNonNullDefault: "argNonNullDefault", + argNullDefault: "argNullDefault", + argNull: "argNull" + ) + `) + @Query() + rawMultilineAndLeadingWhiteSpaces(): boolean { + return true; + } + } - expect(fields).toHaveProperty("withDirective"); - expect(fields.withDirective).toHaveProperty("astNode"); - assertValidDirective(fields.withDirective.astNode, "bar"); + schema = await buildSchema({ + resolvers: [SampleResolver], + directives: [testDirective], + validate: false, }); + schema = testDirectiveTransformer(schema); + }); - it("adds inherited field directives to object type fields while extending interface type class", async () => { - const fields = (schema.getType("ObjectImplement") as GraphQLObjectType).getFields(); + it("should properly emit directive in AST", () => { + const multilineInfo = schema.getRootType(OperationTypeNode.QUERY)!.getFields().multiline; + const leadingWhiteSpacesInfo = schema + .getRootType(OperationTypeNode.QUERY)! + .getFields().leadingWhiteSpaces; + const multilineAndLeadingWhiteSpacesInfo = schema + .getRootType(OperationTypeNode.QUERY)! + .getFields().multilineAndLeadingWhiteSpaces; + const rawMultilineAndLeadingWhiteSpacesInfo = schema + .getRootType(OperationTypeNode.QUERY)! + .getFields().rawMultilineAndLeadingWhiteSpaces; + + expect(() => { + assertValidDirective(multilineInfo.astNode, "test"); + assertValidDirective(leadingWhiteSpacesInfo.astNode, "test"); + assertValidDirective(multilineAndLeadingWhiteSpacesInfo.astNode, "test"); + assertValidDirective(rawMultilineAndLeadingWhiteSpacesInfo.astNode, "test", { + argNonNullDefault: `"argNonNullDefault"`, + argNullDefault: `"argNullDefault"`, + argNull: `"argNull"`, + }); + }).not.toThrow(); + }); - expect(fields).toHaveProperty("withDirective"); - expect(fields.withDirective).toHaveProperty("astNode"); - assertValidDirective(fields.withDirective.astNode, "bar"); + it("should properly apply directive mapper", async () => { + const multilineInfo = schema.getRootType(OperationTypeNode.QUERY)!.getFields().multiline; + const leadingWhiteSpacesInfo = schema + .getRootType(OperationTypeNode.QUERY)! + .getFields().leadingWhiteSpaces; + const multilineAndLeadingWhiteSpacesInfo = schema + .getRootType(OperationTypeNode.QUERY)! + .getFields().multilineAndLeadingWhiteSpaces; + const rawMultilineAndLeadingWhiteSpacesInfo = schema + .getRootType(OperationTypeNode.QUERY)! + .getFields().rawMultilineAndLeadingWhiteSpaces; + + expect(multilineInfo.extensions).toMatchObject({ + TypeGraphQL: { isMappedByDirective: true }, + }); + expect(leadingWhiteSpacesInfo.extensions).toMatchObject({ + TypeGraphQL: { isMappedByDirective: true }, + }); + expect(multilineAndLeadingWhiteSpacesInfo.extensions).toMatchObject({ + TypeGraphQL: { isMappedByDirective: true }, + }); + expect(rawMultilineAndLeadingWhiteSpacesInfo.extensions).toMatchObject({ + TypeGraphQL: { isMappedByDirective: true }, }); }); }); @@ -546,8 +683,6 @@ describe("Directives", () => { }); it("throws error on multiple directive definitions", async () => { - expect.assertions(2); - @Resolver() class InvalidQuery { @Query() @@ -557,20 +692,15 @@ describe("Directives", () => { } } - try { - await buildSchema({ resolvers: [InvalidQuery] }); - } catch (err) { - expect(err).toBeInstanceOf(InvalidDirectiveError); - const error: InvalidDirectiveError = err; - expect(error.message).toContain( - 'Please pass only one directive name or definition at a time to the @Directive decorator "@upper @append"', - ); - } + const error = await expectToThrow(() => buildSchema({ resolvers: [InvalidQuery] })); + + expect(error).toBeInstanceOf(InvalidDirectiveError); + expect(error.message).toContain( + 'Please pass only one directive name or definition at a time to the @Directive decorator "@upper @append"', + ); }); it("throws error when parsing invalid directives", async () => { - expect.assertions(2); - @Resolver() class InvalidQuery { @Query() @@ -580,20 +710,13 @@ describe("Directives", () => { } } - try { - await buildSchema({ resolvers: [InvalidQuery] }); - } catch (err) { - expect(err).toBeInstanceOf(InvalidDirectiveError); - const error: InvalidDirectiveError = err; - expect(error.message).toContain( - 'Error parsing directive definition "@invalid(@directive)"', - ); - } + const error = await expectToThrow(() => buildSchema({ resolvers: [InvalidQuery] })); + + expect(error).toBeInstanceOf(InvalidDirectiveError); + expect(error.message).toContain('Error parsing directive definition "@invalid(@directive)"'); }); it("throws error when no directives are defined", async () => { - expect.assertions(2); - @Resolver() class InvalidQuery { @Query() @@ -603,15 +726,12 @@ describe("Directives", () => { } } - try { - await buildSchema({ resolvers: [InvalidQuery] }); - } catch (err) { - expect(err).toBeInstanceOf(InvalidDirectiveError); - const error: InvalidDirectiveError = err; - expect(error.message).toContain( - "Please pass at-least one directive name or definition to the @Directive decorator", - ); - } + const error = await expectToThrow(() => buildSchema({ resolvers: [InvalidQuery] })); + + expect(error).toBeInstanceOf(InvalidDirectiveError); + expect(error.message).toContain( + "Please pass at-least one directive name or definition to the @Directive decorator", + ); }); }); }); diff --git a/tests/functional/emit-schema-sdl.ts b/tests/functional/emit-schema-sdl.ts index edf9b77f2..1e0cf49fd 100644 --- a/tests/functional/emit-schema-sdl.ts +++ b/tests/functional/emit-schema-sdl.ts @@ -1,22 +1,22 @@ import "reflect-metadata"; -import { GraphQLSchema } from "graphql"; -import fs from "fs"; -import path from "path"; -import rimraf from "rimraf"; - +import fs from "node:fs"; +import asyncFs from "node:fs/promises"; +import path from "node:path"; +import { type GraphQLSchema } from "graphql"; +import shelljs from "shelljs"; import { - buildSchema, - buildSchemaSync, - emitSchemaDefinitionFile, - emitSchemaDefinitionFileSync, Field, ObjectType, + type PrintSchemaOptions, Query, Resolver, - PrintSchemaOptions, + buildSchema, + buildSchemaSync, defaultPrintSchemaOptions, -} from "../../src"; -import * as filesystem from "../../src/helpers/filesystem"; + emitSchemaDefinitionFile, + emitSchemaDefinitionFileSync, +} from "type-graphql"; +import { expectToThrow } from "../helpers/expectToThrow"; const TEST_DIR = path.resolve(process.cwd(), "tests", "test-output-dir"); @@ -28,10 +28,10 @@ describe("Emitting schema definition file", () => { @ObjectType() class MyObject { @Field() - normalProperty: string; + normalProperty!: string; @Field({ description: "Description test" }) - descriptionProperty: boolean; + descriptionProperty!: boolean; } @Resolver() @@ -49,14 +49,14 @@ describe("Emitting schema definition file", () => { }); }); - afterEach(done => { + afterEach(() => { jest.restoreAllMocks(); - rimraf(TEST_DIR, done); + shelljs.rm("-rf", TEST_DIR); }); function checkSchemaSDL( SDL: string, - { commentDescriptions, sortedSchema }: PrintSchemaOptions = defaultPrintSchemaOptions, + { sortedSchema }: PrintSchemaOptions = defaultPrintSchemaOptions, ) { expect(SDL).toContain("THIS FILE WAS GENERATED"); expect(SDL).toContain("MyObject"); @@ -65,25 +65,20 @@ describe("Emitting schema definition file", () => { } else { expect(SDL.indexOf("descriptionProperty")).toBeGreaterThan(SDL.indexOf("normalProperty")); } - if (commentDescriptions) { - expect(SDL).toContain(`# Description test`); - } else { - expect(SDL).toContain(`"""Description test"""`); - } + expect(SDL).toContain(`"""Description test"""`); } describe("emitSchemaDefinitionFile", () => { it("should write file with schema SDL successfully", async () => { - const targetPath = path.join(TEST_DIR, "schemas", "test1", "schema.gql"); + const targetPath = path.join(TEST_DIR, "schemas", "test1", "schema.graphql"); await emitSchemaDefinitionFile(targetPath, schema); expect(fs.existsSync(targetPath)).toEqual(true); checkSchemaSDL(fs.readFileSync(targetPath).toString()); }); it("should use provided options to write file with schema SDL", async () => { - const targetPath = path.join(TEST_DIR, "schemas", "test1", "schema.gql"); + const targetPath = path.join(TEST_DIR, "schemas", "test1", "schema.graphql"); const options: PrintSchemaOptions = { - commentDescriptions: true, sortedSchema: false, }; await emitSchemaDefinitionFile(targetPath, schema, options); @@ -92,8 +87,8 @@ describe("Emitting schema definition file", () => { }); it("should throw error when unknown error occur while writing file with schema SDL", async () => { - jest.spyOn(filesystem, "fsWriteFile").mockRejectedValueOnce({ code: "TEST ERROR" }); - const targetPath = path.join(TEST_DIR, "schemas", "fail1", "schema.gql"); + jest.spyOn(asyncFs, "writeFile").mockRejectedValueOnce({ code: "TEST ERROR" }); + const targetPath = path.join(TEST_DIR, "schemas", "fail1", "schema.graphql"); let error; try { await emitSchemaDefinitionFile(targetPath, schema); @@ -105,8 +100,8 @@ describe("Emitting schema definition file", () => { }); it("should throw error when unknown error occur while creating directory with schema SDL", async () => { - jest.spyOn(filesystem, "fsMkdir").mockRejectedValueOnce({ code: "TEST ERROR" }); - const targetPath = path.join(TEST_DIR, "schemas", "fail2", "schema.gql"); + jest.spyOn(asyncFs, "mkdir").mockRejectedValueOnce({ code: "TEST ERROR" }); + const targetPath = path.join(TEST_DIR, "schemas", "fail2", "schema.graphql"); let error; try { await emitSchemaDefinitionFile(targetPath, schema); @@ -120,16 +115,15 @@ describe("Emitting schema definition file", () => { describe("emitSchemaDefinitionFileSync", () => { it("should write file with schema SDL successfully", async () => { - const targetPath = path.join(TEST_DIR, "schemas", "test2", "schema.gql"); + const targetPath = path.join(TEST_DIR, "schemas", "test2", "schema.graphql"); emitSchemaDefinitionFileSync(targetPath, schema); expect(fs.existsSync(targetPath)).toEqual(true); checkSchemaSDL(fs.readFileSync(targetPath).toString()); }); it("should use provided options to write file with schema SDL", async () => { - const targetPath = path.join(TEST_DIR, "schemas", "test1", "schema.gql"); + const targetPath = path.join(TEST_DIR, "schemas", "test1", "schema.graphql"); const options: PrintSchemaOptions = { - commentDescriptions: true, sortedSchema: false, }; emitSchemaDefinitionFileSync(targetPath, schema, options); @@ -137,40 +131,32 @@ describe("Emitting schema definition file", () => { checkSchemaSDL(fs.readFileSync(targetPath).toString(), options); }); - it("should throw error when unknown error occur while writing file with schema SDL", () => { + it("should throw error when unknown error occur while writing file with schema SDL", async () => { jest.spyOn(fs, "writeFileSync").mockImplementationOnce(() => { - throw { code: "TEST ERROR" }; + throw new Error("TYPE_GRAPHQL_WRITE_FILE_SYNC_ERROR"); }); - const targetPath = path.join(TEST_DIR, "schemas", "fail3", "schema.gql"); - let error; - try { - emitSchemaDefinitionFileSync(targetPath, schema); - } catch (e) { - error = e; - } - expect(error).toEqual({ code: "TEST ERROR" }); + const targetPath = path.join(TEST_DIR, "schemas", "fail3", "schema.graphql"); + const error = await expectToThrow(() => emitSchemaDefinitionFileSync(targetPath, schema)); + + expect(error.message).toStrictEqual("TYPE_GRAPHQL_WRITE_FILE_SYNC_ERROR"); expect(fs.existsSync(targetPath)).toEqual(false); }); - it("should throw error when unknown error occur while creating directory with schema SDL", () => { + it("should throw error when unknown error occur while creating directory with schema SDL", async () => { jest.spyOn(fs, "mkdirSync").mockImplementationOnce(() => { - throw { code: "TEST ERROR" }; + throw new Error("TYPE_GRAPHQL_MKDIR_SYNC_ERROR"); }); - const targetPath = path.join(TEST_DIR, "schemas", "fail4", "schema.gql"); - let error; - try { - emitSchemaDefinitionFileSync(targetPath, schema); - } catch (e) { - error = e; - } - expect(error).toEqual({ code: "TEST ERROR" }); + const targetPath = path.join(TEST_DIR, "schemas", "fail4", "schema.graphql"); + const error = await expectToThrow(() => emitSchemaDefinitionFileSync(targetPath, schema)); + + expect(error.message).toStrictEqual("TYPE_GRAPHQL_MKDIR_SYNC_ERROR"); expect(fs.existsSync(targetPath)).toEqual(false); }); }); describe("buildSchema", () => { it("should generate schema SDL file on selected file path", async () => { - const targetPath = path.join(TEST_DIR, "schemas", "test3", "schema.gql"); + const targetPath = path.join(TEST_DIR, "schemas", "test3", "schema.graphql"); await buildSchema({ resolvers: [MyResolverClass], emitSchemaFile: targetPath, @@ -181,7 +167,7 @@ describe("Emitting schema definition file", () => { it("should generate schema SDL file in current working dir", async () => { jest.spyOn(process, "cwd").mockImplementation(() => TEST_DIR); - const targetPath = path.join(process.cwd(), "schema.gql"); + const targetPath = path.join(process.cwd(), "schema.graphql"); await buildSchema({ resolvers: [MyResolverClass], emitSchemaFile: true, @@ -191,42 +177,37 @@ describe("Emitting schema definition file", () => { }); it("should read EmitSchemaFileOptions and apply them in emit", async () => { - const targetPath = path.join(TEST_DIR, "schemas", "test4", "schema.gql"); + const targetPath = path.join(TEST_DIR, "schemas", "test4", "schema.graphql"); await buildSchema({ resolvers: [MyResolverClass], emitSchemaFile: { - commentDescriptions: true, path: targetPath, sortedSchema: false, }, }); expect(fs.existsSync(targetPath)).toEqual(true); checkSchemaSDL(fs.readFileSync(targetPath).toString(), { - commentDescriptions: true, sortedSchema: false, }); }); it("should read EmitSchemaFileOptions and set default path and sorting schema", async () => { jest.spyOn(process, "cwd").mockImplementation(() => TEST_DIR); - const targetPath = path.join(process.cwd(), "schema.gql"); + const targetPath = path.join(process.cwd(), "schema.graphql"); await buildSchema({ resolvers: [MyResolverClass], - emitSchemaFile: { - commentDescriptions: true, - }, + emitSchemaFile: {}, }); expect(fs.existsSync(targetPath)).toEqual(true); checkSchemaSDL(fs.readFileSync(targetPath).toString(), { ...defaultPrintSchemaOptions, - commentDescriptions: true, }); }); }); describe("buildSchemaSync", () => { it("should synchronously generate schema SDL file on selected file path", async () => { - const targetPath = path.join(TEST_DIR, "schemas", "test5", "schema.gql"); + const targetPath = path.join(TEST_DIR, "schemas", "test5", "schema.graphql"); buildSchemaSync({ resolvers: [MyResolverClass], emitSchemaFile: targetPath, @@ -237,7 +218,7 @@ describe("Emitting schema definition file", () => { it("should generate schema SDL file in current working dir", async () => { jest.spyOn(process, "cwd").mockImplementation(() => TEST_DIR); - const targetPath = path.join(process.cwd(), "schema.gql"); + const targetPath = path.join(process.cwd(), "schema.graphql"); buildSchemaSync({ resolvers: [MyResolverClass], emitSchemaFile: true, @@ -247,35 +228,30 @@ describe("Emitting schema definition file", () => { }); it("should read EmitSchemaFileOptions and apply them in emit", async () => { - const targetPath = path.join(TEST_DIR, "schemas", "test6", "schema.gql"); + const targetPath = path.join(TEST_DIR, "schemas", "test6", "schema.graphql"); buildSchemaSync({ resolvers: [MyResolverClass], emitSchemaFile: { - commentDescriptions: true, path: targetPath, sortedSchema: false, }, }); expect(fs.existsSync(targetPath)).toEqual(true); checkSchemaSDL(fs.readFileSync(targetPath).toString(), { - commentDescriptions: true, sortedSchema: false, }); }); it("should read EmitSchemaFileOptions and set default path and sorting schema", async () => { jest.spyOn(process, "cwd").mockImplementation(() => TEST_DIR); - const targetPath = path.join(process.cwd(), "schema.gql"); + const targetPath = path.join(process.cwd(), "schema.graphql"); buildSchemaSync({ resolvers: [MyResolverClass], - emitSchemaFile: { - commentDescriptions: true, - }, + emitSchemaFile: {}, }); expect(fs.existsSync(targetPath)).toEqual(true); checkSchemaSDL(fs.readFileSync(targetPath).toString(), { ...defaultPrintSchemaOptions, - commentDescriptions: true, }); }); }); diff --git a/tests/functional/enums.ts b/tests/functional/enums.ts index 0caaebda3..65257a5be 100644 --- a/tests/functional/enums.ts +++ b/tests/functional/enums.ts @@ -1,21 +1,20 @@ import "reflect-metadata"; import { - IntrospectionSchema, - IntrospectionObjectType, - IntrospectionInputObjectType, - IntrospectionEnumType, - graphql, - GraphQLSchema, + type GraphQLSchema, + type IntrospectionEnumType, + type IntrospectionInputObjectType, + type IntrospectionObjectType, + type IntrospectionSchema, TypeKind, + graphql, } from "graphql"; - -import { getSchemaInfo } from "../helpers/getSchemaInfo"; +import { Arg, Field, InputType, Query, registerEnumType } from "type-graphql"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; import { getInnerInputFieldType, getInnerTypeOfNonNullableType, } from "../helpers/getInnerFieldType"; -import { getMetadataStorage } from "../../src/metadata/getMetadataStorage"; -import { Field, InputType, Query, Arg, registerEnumType } from "../../src"; +import { getSchemaInfo } from "../helpers/getSchemaInfo"; describe("Enums", () => { let schemaIntrospection: IntrospectionSchema; @@ -54,39 +53,39 @@ describe("Enums", () => { @InputType() class NumberEnumInput { - @Field(type => NumberEnum) - numberEnumField: NumberEnum; + @Field(() => NumberEnum) + numberEnumField!: NumberEnum; } @InputType() class StringEnumInput { - @Field(type => StringEnum) - stringEnumField: StringEnum; + @Field(() => StringEnum) + stringEnumField!: StringEnum; } class SampleResolver { - @Query(returns => NumberEnum) - getNumberEnumValue(@Arg("input") input: NumberEnumInput): NumberEnum { + @Query(_returns => NumberEnum) + getNumberEnumValue(@Arg("input") _input: NumberEnumInput): NumberEnum { return NumberEnum.Two; } - @Query(returns => StringEnum) - getStringEnumValue(@Arg("input") input: StringEnumInput): StringEnum { + @Query(() => StringEnum) + getStringEnumValue(@Arg("input") _input: StringEnumInput): StringEnum { return StringEnum.Two; } - @Query(returns => AdvancedEnum) + @Query(() => AdvancedEnum) getAdvancedEnumValue(): AdvancedEnum { return AdvancedEnum.DescriptionProperty; } @Query() - isNumberEnumEqualOne(@Arg("enum", type => NumberEnum) numberEnum: NumberEnum): boolean { + isNumberEnumEqualOne(@Arg("enum", () => NumberEnum) numberEnum: NumberEnum): boolean { return numberEnum === NumberEnum.One; } @Query() - isStringEnumEqualOne(@Arg("enum", type => StringEnum) stringEnum: StringEnum): boolean { + isStringEnumEqualOne(@Arg("enum", () => StringEnum) stringEnum: StringEnum): boolean { return stringEnum === StringEnum.One; } } @@ -209,7 +208,7 @@ describe("Enums", () => { const query = `query { getNumberEnumValue(input: { numberEnumField: One }) }`; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); expect(result.data!.getNumberEnumValue).toEqual("Two"); }); @@ -218,7 +217,7 @@ describe("Enums", () => { const query = `query { getStringEnumValue(input: { stringEnumField: One }) }`; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); expect(result.data!.getStringEnumValue).toEqual("Two"); }); @@ -231,8 +230,8 @@ describe("Enums", () => { isNumberEnumEqualOne(enum: Two) }`; - const result1 = await graphql(schema, query1); - const result2 = await graphql(schema, query2); + const result1 = await graphql({ schema, source: query1 }); + const result2 = await graphql({ schema, source: query2 }); expect(result1.data!.isNumberEnumEqualOne).toEqual(true); expect(result2.data!.isNumberEnumEqualOne).toEqual(false); @@ -246,8 +245,8 @@ describe("Enums", () => { isStringEnumEqualOne(enum: Two) }`; - const result1 = await graphql(schema, query1); - const result2 = await graphql(schema, query2); + const result1 = await graphql({ schema, source: query1 }); + const result2 = await graphql({ schema, source: query2 }); expect(result1.data!.isStringEnumEqualOne).toEqual(true); expect(result2.data!.isStringEnumEqualOne).toEqual(false); diff --git a/tests/functional/errors/metadata-polyfill.ts b/tests/functional/errors/metadata-polyfill.ts index 63140a1a7..58df19c8d 100644 --- a/tests/functional/errors/metadata-polyfill.ts +++ b/tests/functional/errors/metadata-polyfill.ts @@ -1,14 +1,19 @@ -import { ReflectMetadataMissingError } from "../../../src"; -import { getMetadataStorage } from "../../../src/metadata/getMetadataStorage"; +import { ReflectMetadataMissingError } from "type-graphql"; +import { findType } from "@/helpers/findType"; +import { expectToThrow } from "../../helpers/expectToThrow"; describe("Reflect metadata", () => { it("should throw ReflectMetadataMissingError when no polyfill provided", async () => { - try { - getMetadataStorage(); - } catch (err) { - expect(err).toBeInstanceOf(ReflectMetadataMissingError); - expect(err.message).toContain("metadata"); - expect(err.message).toContain("polyfill"); - } + const error = await expectToThrow(() => + findType({ + metadataKey: "design:type", + prototype: {}, + propertyKey: "test", + }), + ); + + expect(error).toBeInstanceOf(ReflectMetadataMissingError); + expect(error.message).toContain("metadata"); + expect(error.message).toContain("polyfill"); }); }); diff --git a/tests/functional/extensions.ts b/tests/functional/extensions.ts index 8511fc27f..63b05e1da 100644 --- a/tests/functional/extensions.ts +++ b/tests/functional/extensions.ts @@ -1,19 +1,23 @@ import "reflect-metadata"; - -import { GraphQLSchema, GraphQLInputObjectType, GraphQLObjectType, GraphQLFieldMap } from "graphql"; import { + type GraphQLFieldMap, + type GraphQLInputObjectType, + type GraphQLObjectType, + type GraphQLSchema, +} from "graphql"; +import { + Arg, + Extensions, Field, + FieldResolver, InputType, - Resolver, + Mutation, + ObjectType, Query, - Arg, - Extensions, + Resolver, buildSchema, - ObjectType, - Mutation, - FieldResolver, -} from "../../src"; -import { getMetadataStorage } from "../../src/metadata/getMetadataStorage"; +} from "type-graphql"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; describe("Extensions", () => { let schema: GraphQLSchema; @@ -26,21 +30,21 @@ describe("Extensions", () => { class ExtensionsOnFieldInput { @Field() @Extensions({ role: "admin" }) - withExtensions: string; + withExtensions!: string; } @InputType() @Extensions({ roles: ["admin", "user"] }) class ExtensionsOnClassInput { @Field() - regularField: string; + regularField!: string; } @ObjectType() @Extensions({ id: 1234 }) class ExtensionsOnClassObjectType { @Field() - regularField: string; + regularField!: string; } @ObjectType() @@ -137,7 +141,7 @@ describe("Extensions", () => { } } - @Resolver(of => SampleObjectType) + @Resolver(() => SampleObjectType) class SampleObjectTypeResolver { @FieldResolver() @Extensions({ some: "extension" }) @@ -250,9 +254,9 @@ describe("Extensions", () => { }); it("should add extensions to input type fields", async () => { - const fields = (schema.getType( - "ExtensionsOnFieldInput", - ) as GraphQLInputObjectType).getFields(); + const fields = ( + schema.getType("ExtensionsOnFieldInput") as GraphQLInputObjectType + ).getFields(); expect(fields.withExtensions.extensions).toEqual({ role: "admin" }); }); @@ -332,7 +336,7 @@ describe("Extensions", () => { @Extensions({ childField: true }) childField!: string; } - @Resolver(of => Child) + @Resolver(() => Child) class ChildResolver { @Query() sampleQuery(): Child { diff --git a/tests/functional/fields.ts b/tests/functional/fields.ts index ccf4544db..649dfa8e9 100644 --- a/tests/functional/fields.ts +++ b/tests/functional/fields.ts @@ -1,23 +1,20 @@ import "reflect-metadata"; import { - IntrospectionSchema, - IntrospectionObjectType, - IntrospectionNonNullTypeRef, - IntrospectionNamedTypeRef, - IntrospectionListTypeRef, + type IntrospectionListTypeRef, + type IntrospectionNamedTypeRef, + type IntrospectionNonNullTypeRef, + type IntrospectionObjectType, + type IntrospectionScalarType, + type IntrospectionSchema, TypeKind, - IntrospectionScalarType, } from "graphql"; - -import { getMetadataStorage } from "../../src/metadata/getMetadataStorage"; +import { Field, GraphQLISODateTime, ObjectType, Query, Resolver } from "type-graphql"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { expectToThrow } from "../helpers/expectToThrow"; import { getSchemaInfo } from "../helpers/getSchemaInfo"; -import { ObjectType, Field, Query, Resolver, GraphQLISODateTime } from "../../src"; -import { NullableListOptions } from "../../src/decorators/types"; describe("Fields - schema", () => { let schemaIntrospection: IntrospectionSchema; - let queryType: IntrospectionObjectType; - let mutationType: IntrospectionObjectType; let sampleObjectType: IntrospectionObjectType; beforeAll(async () => { @@ -26,61 +23,61 @@ describe("Fields - schema", () => { @ObjectType() class SampleNestedObject { @Field() - stringField: string; + stringField!: string; } @ObjectType() class SampleObject { @Field() - implicitStringField: string; + implicitStringField!: string; - @Field(type => String) + @Field(() => String) explicitStringField: any; @Field() - implicitObjectField: SampleNestedObject; + implicitObjectField!: SampleNestedObject; - @Field(type => String, { nullable: true }) + @Field(() => String, { nullable: true }) explicitNullableStringField: any; @Field({ nullable: true }) - implicitNullableStringField: string; + implicitNullableStringField!: string; - @Field(type => [String]) - explicitStringArrayField: string[]; + @Field(() => [String]) + explicitStringArrayField!: string[]; - @Field(type => [String], { nullable: true }) - nullableArrayFieldNew: string[] | null; + @Field(() => [String], { nullable: true }) + nullableArrayFieldNew!: string[] | null; - @Field(type => [SampleNestedObject], { nullable: true }) - nullableObjectArrayField: SampleNestedObject[] | null; + @Field(() => [SampleNestedObject], { nullable: true }) + nullableObjectArrayField!: SampleNestedObject[] | null; - @Field(typoe => [String], { nullable: "itemsAndList" }) - arrayWithNullableItemField: String[]; + @Field(() => [String], { nullable: "itemsAndList" }) + arrayWithNullableItemField!: string[]; - @Field(typoe => [String], { nullable: "items" }) - nonnullArrayWithNullableItemField: String[]; + @Field(() => [String], { nullable: "items" }) + nonNullArrayWithNullableItemField!: string[]; @Field({ name: "overwrittenName", nullable: true }) - overwrittenStringField: string; + overwrittenStringField!: string; @Field({ name: "complexField", complexity: 10 }) - complexField: string; + complexField!: string; - @Field(type => [[String]], { nullable: true }) - nullableNestedArrayField: string[][] | null; + @Field(() => [[String]], { nullable: true }) + nullableNestedArrayField!: string[][] | null; - @Field(type => [[String]], { nullable: "items" }) - nonNullNestedArrayWithNullableItemField: Array | null>; + @Field(() => [[String]], { nullable: "items" }) + nonNullNestedArrayWithNullableItemField!: Array | null>; - @Field(type => [[String]], { nullable: "itemsAndList" }) - nestedArrayWithNullableItemField: Array | null> | null; + @Field(() => [[String]], { nullable: "itemsAndList" }) + nestedArrayWithNullableItemField!: Array | null> | null; - @Field(type => GraphQLISODateTime) - overwrittenArrayScalarField: string[]; + @Field(() => GraphQLISODateTime) + overwrittenArrayScalarField!: string[]; } - @Resolver(of => SampleObject) + @Resolver(() => SampleObject) class SampleResolver { @Query() sampleQuery(): SampleObject { @@ -93,8 +90,6 @@ describe("Fields - schema", () => { resolvers: [SampleResolver], }); schemaIntrospection = schemaInfo.schemaIntrospection; - queryType = schemaInfo.queryType; - mutationType = schemaInfo.mutationType!; sampleObjectType = schemaIntrospection.types.find( type => type.name === "SampleObject", ) as IntrospectionObjectType; @@ -111,7 +106,7 @@ describe("Fields - schema", () => { expect(schemaIntrospection).toBeDefined(); }); - it("it should register complexity info for field", async () => { + it("should register complexity info for field", async () => { const metadataStorage = getMetadataStorage(); const sampleObj = metadataStorage.objectTypes.find(it => it.name === "SampleObject")!; const complexField = sampleObj.fields!.find(it => it.name === "complexField")!; @@ -119,73 +114,70 @@ describe("Fields - schema", () => { }); it("should throw error when field type not provided", async () => { - expect.assertions(3); getMetadataStorage().clear(); - try { + const error = await expectToThrow(() => { @ObjectType() + // eslint-disable-next-line @typescript-eslint/no-unused-vars class SampleObject { @Field() invalidSampleField: any; } - } catch (err) { - expect(err).toBeInstanceOf(Error); - const error: Error = err; - expect(error.message).toContain("provide explicit type"); - expect(error.message).toContain("invalidSampleField"); - } + }); + + expect(error).toBeInstanceOf(Error); + expect(error.message).toContain("provide explicit type"); + expect(error.message).toContain("invalidSampleField"); }); it("should throw error when field type is array and no explicit type provided", async () => { - expect.assertions(3); getMetadataStorage().clear(); - try { + const error = await expectToThrow(() => { @ObjectType() + // eslint-disable-next-line @typescript-eslint/no-unused-vars class SampleObject { @Field() - invalidSampleArrayField: string[]; + invalidSampleArrayField!: string[]; } - } catch (err) { - expect(err).toBeInstanceOf(Error); - const error: Error = err; - expect(error.message).toContain("provide explicit type"); - expect(error.message).toContain("invalidSampleArrayField"); - } + }); + + expect(error).toBeInstanceOf(Error); + expect(error.message).toContain("provide explicit type"); + expect(error.message).toContain("invalidSampleArrayField"); }); it("should throw error when cannot determine field type", async () => { - expect.assertions(3); getMetadataStorage().clear(); - try { + const error = await expectToThrow(() => { @ObjectType() + // eslint-disable-next-line @typescript-eslint/no-unused-vars class SampleObject { @Field({ nullable: true }) - invalidSampleNullableField: string | null; + invalidSampleNullableField!: string | null; } - } catch (err) { - expect(err).toBeInstanceOf(Error); - const error: Error = err; - expect(error.message).toContain("provide explicit type"); - expect(error.message).toContain("invalidSampleNullableField"); - } + }); + + expect(error).toBeInstanceOf(Error); + expect(error.message).toContain("provide explicit type"); + expect(error.message).toContain("invalidSampleNullableField"); }); it("should throw error when object type property key is symbol", async () => { - expect.assertions(1); getMetadataStorage().clear(); const symbolKey = Symbol("symbolKey"); - try { + const error = await expectToThrow(() => { @ObjectType() + // eslint-disable-next-line @typescript-eslint/no-unused-vars class SampleObject { @Field({ nullable: true }) - [symbolKey]: string | null; + [symbolKey]!: string | null; } - } catch (err) { - expect(err.message).toContain("Symbol keys are not supported yet!"); - } + }); + + expect(error.message).toContain("Symbol keys are not supported yet!"); }); it("should generate non-nullable field type by default", async () => { @@ -285,23 +277,23 @@ describe("Fields - schema", () => { expect(arrayItemFieldType.name).toEqual("SampleNestedObject"); }); - it("should generate nullable item array with nullalbe option 'itemAndList'", async () => { + it("should generate nullable item array with nullable option 'itemAndList'", async () => { const arrayWithNullableItemField = sampleObjectType.fields.find( field => field.name === "arrayWithNullableItemField", )!; const nullableArrayType = arrayWithNullableItemField.type as IntrospectionListTypeRef; - const nullableItemtype = nullableArrayType.ofType as IntrospectionNamedTypeRef; + const nullableItemType = nullableArrayType.ofType as IntrospectionNamedTypeRef; expect(nullableArrayType.kind).toEqual(TypeKind.LIST); - expect(nullableItemtype.kind).toEqual(TypeKind.SCALAR); - expect(nullableItemtype.name).toEqual("String"); + expect(nullableItemType.kind).toEqual(TypeKind.SCALAR); + expect(nullableItemType.name).toEqual("String"); }); - it("should generate nullable element nonnull array with nullable option 'item'", async () => { - const nonnullArrayWithNullableItemField = sampleObjectType.fields.find( - field => field.name === "nonnullArrayWithNullableItemField", + it("should generate nullable element nonNull array with nullable option 'item'", async () => { + const nonNullArrayWithNullableItemField = sampleObjectType.fields.find( + field => field.name === "nonNullArrayWithNullableItemField", )!; - const nonNullArrayType = nonnullArrayWithNullableItemField.type as IntrospectionNonNullTypeRef; + const nonNullArrayType = nonNullArrayWithNullableItemField.type as IntrospectionNonNullTypeRef; const arrayType = nonNullArrayType.ofType as IntrospectionListTypeRef; const elementType = arrayType.ofType as IntrospectionNamedTypeRef; @@ -332,8 +324,10 @@ describe("Fields - schema", () => { const arrayFieldType = nullableNestedArrayField.type as IntrospectionListTypeRef; const arrayItemNonNullFieldType = arrayFieldType.ofType as IntrospectionNonNullTypeRef; const arrayItemFieldType = arrayItemNonNullFieldType.ofType as IntrospectionListTypeRef; - const arrayItemScalarNonNullFieldType = arrayItemFieldType.ofType as IntrospectionNonNullTypeRef; - const arrayItemScalarFieldType = arrayItemScalarNonNullFieldType.ofType as IntrospectionNamedTypeRef; + const arrayItemScalarNonNullFieldType = + arrayItemFieldType.ofType as IntrospectionNonNullTypeRef; + const arrayItemScalarFieldType = + arrayItemScalarNonNullFieldType.ofType as IntrospectionNamedTypeRef; expect(arrayFieldType.kind).toEqual(TypeKind.LIST); expect(arrayItemNonNullFieldType.kind).toEqual(TypeKind.NON_NULL); @@ -378,11 +372,13 @@ describe("Fields - schema", () => { const overwrittenArrayScalarField = sampleObjectType.fields.find( field => field.name === "overwrittenArrayScalarField", )!; - const overwrittenArrayScalarFieldType = overwrittenArrayScalarField.type as IntrospectionNonNullTypeRef; - const overwrittenArrayScalarFieldInnerType = overwrittenArrayScalarFieldType.ofType as IntrospectionScalarType; + const overwrittenArrayScalarFieldType = + overwrittenArrayScalarField.type as IntrospectionNonNullTypeRef; + const overwrittenArrayScalarFieldInnerType = + overwrittenArrayScalarFieldType.ofType as IntrospectionScalarType; expect(overwrittenArrayScalarFieldType.kind).toEqual(TypeKind.NON_NULL); expect(overwrittenArrayScalarFieldInnerType.kind).toEqual(TypeKind.SCALAR); - expect(overwrittenArrayScalarFieldInnerType.name).toEqual("DateTime"); + expect(overwrittenArrayScalarFieldInnerType.name).toEqual("DateTimeISO"); }); }); diff --git a/tests/functional/generic-types.ts b/tests/functional/generic-types.ts index cda2789b4..aeae47b87 100644 --- a/tests/functional/generic-types.ts +++ b/tests/functional/generic-types.ts @@ -1,47 +1,46 @@ import "reflect-metadata"; import { - IntrospectionObjectType, - IntrospectionInterfaceType, - IntrospectionNonNullTypeRef, - IntrospectionScalarType, + type GraphQLSchema, + type IntrospectionInputObjectType, + type IntrospectionInterfaceType, + type IntrospectionListTypeRef, + type IntrospectionNonNullTypeRef, + type IntrospectionObjectType, + type IntrospectionScalarType, + type IntrospectionSchema, TypeKind, - IntrospectionListTypeRef, graphql, - GraphQLSchema, - IntrospectionSchema, - IntrospectionInputObjectType, } from "graphql"; - -import { getSchemaInfo } from "../helpers/getSchemaInfo"; -import { getMetadataStorage } from "../../src/metadata/getMetadataStorage"; import { - ObjectType, + Arg, + type ClassType, Field, - Resolver, - Query, - InterfaceType, - ClassType, - Int, InputType, - Arg, -} from "../../src"; + Int, + InterfaceType, + ObjectType, + Query, + Resolver, +} from "type-graphql"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { getSchemaInfo } from "../helpers/getSchemaInfo"; describe("Generic types", () => { beforeEach(() => { getMetadataStorage().clear(); }); - it("shouldn't emit abstract object type", async () => { - @ObjectType({ isAbstract: true }) + it("shouldn't emit unused abstract object type", async () => { + @ObjectType() abstract class BaseType { @Field() - baseField: string; + baseField!: string; } @ObjectType() class SampleType extends BaseType { @Field() - sampleField: string; + sampleField!: string; } @Resolver() @@ -66,25 +65,26 @@ describe("Generic types", () => { expect(baseTypeInfo).toBeUndefined(); }); - it("shouldn't emit abstract interface type", async () => { - @InterfaceType({ isAbstract: true }) + it("shouldn't emit unused abstract interface type", async () => { + @InterfaceType() abstract class BaseInterfaceType { @Field() - baseField: string; + baseField!: string; } @InterfaceType() abstract class SampleInterfaceType extends BaseInterfaceType { @Field() - sampleField: string; + sampleField!: string; } @ObjectType({ implements: SampleInterfaceType }) class SampleType implements SampleInterfaceType { @Field() - baseField: string; + baseField!: string; + @Field() - sampleField: string; + sampleField!: string; } @Resolver() @@ -111,23 +111,23 @@ describe("Generic types", () => { expect(baseInterfaceTypeInfo).toBeUndefined(); }); - it("shouldn't emit abstract input object type", async () => { - @InputType({ isAbstract: true }) + it("shouldn't emit unused abstract input object type", async () => { + @InputType() abstract class BaseInput { @Field() - baseField: string; + baseField!: string; } @InputType() class SampleInput extends BaseInput { @Field() - sampleField: string; + sampleField!: string; } @Resolver() class SampleResolver { @Query() - sampleQuery(@Arg("input") input: SampleInput): boolean { + sampleQuery(@Arg("input") _input: SampleInput): boolean { return true; } } @@ -151,14 +151,14 @@ describe("Generic types", () => { let dogsResponseMock: any; beforeEach(async () => { - function Connection(TItemClass: ClassType) { - @ObjectType(`${TItemClass.name}Connection`, { isAbstract: true }) + function Connection(TItemClass: ClassType) { + @ObjectType(`${TItemClass.name}Connection`) class ConnectionClass { - @Field(type => Int) - count: number; + @Field(() => Int) + count!: number; - @Field(type => [TItemClass]) - items: TItem[]; + @Field(() => [TItemClass]) + items!: TItem[]; } return ConnectionClass; } @@ -166,16 +166,17 @@ describe("Generic types", () => { @ObjectType() class User { @Field() - name: string; + name!: string; } @ObjectType() class Dog { @Field() - canBark: boolean; + canBark!: boolean; } const UserConnection = Connection(User); + // eslint-disable-next-line @typescript-eslint/no-redeclare type UserConnection = InstanceType; @ObjectType() class DogConnection extends Connection(Dog) {} @@ -187,7 +188,7 @@ describe("Generic types", () => { @Resolver() class GenericConnectionResolver { - @Query(returns => UserConnection) + @Query(() => UserConnection) users(): UserConnection { return { count: 2, @@ -195,7 +196,7 @@ describe("Generic types", () => { }; } - @Query(returns => DogConnection) + @Query(() => DogConnection) dogs(): DogConnection { return dogsResponseMock; } @@ -216,14 +217,18 @@ describe("Generic types", () => { const userConnectionCountField = userConnectionTypeInfo.fields.find( it => it.name === "count", )!; - const userConnectionCountFieldType = (userConnectionCountField.type as IntrospectionNonNullTypeRef) - .ofType as IntrospectionScalarType; + const userConnectionCountFieldType = ( + userConnectionCountField.type as IntrospectionNonNullTypeRef + ).ofType as IntrospectionScalarType; const userConnectionItemsField = userConnectionTypeInfo.fields.find( it => it.name === "items", )!; - const userConnectionItemsFieldType = (((userConnectionItemsField.type as IntrospectionNonNullTypeRef) - .ofType as IntrospectionListTypeRef).ofType as IntrospectionNonNullTypeRef) - .ofType as IntrospectionObjectType; + const userConnectionItemsFieldType = ( + ( + (userConnectionItemsField.type as IntrospectionNonNullTypeRef) + .ofType as IntrospectionListTypeRef + ).ofType as IntrospectionNonNullTypeRef + ).ofType as IntrospectionObjectType; expect(schemaObjectTypes).toHaveLength(5); // Query, User, Dog, UserCon, DogCon expect(userConnectionTypeInfo.fields).toHaveLength(2); @@ -245,7 +250,7 @@ describe("Generic types", () => { } `; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); expect(result.data!.dogs).toEqual(dogsResponseMock); }); @@ -258,14 +263,14 @@ describe("Generic types", () => { let friendshipEdgeResponse: any; beforeEach(async () => { - function Edge(NodeClass: ClassType) { - @ObjectType({ isAbstract: true }) + function Edge(TNodeClass: ClassType) { + @ObjectType() abstract class EdgeClass { - @Field(type => NodeClass) - node: TNodeClass; + @Field(() => TNodeClass) + node!: TNode; @Field() - cursor: string; + cursor!: string; } return EdgeClass; } @@ -273,19 +278,19 @@ describe("Generic types", () => { @ObjectType() class Recipe { @Field() - title: string; + title!: string; } @ObjectType() class User { @Field() - name: string; + name!: string; } @ObjectType() class RecipeEdge extends Edge(Recipe) { @Field() - personalNotes: string; + personalNotes!: string; } recipeEdgeResponse = { cursor: "recipeCursor", @@ -298,7 +303,7 @@ describe("Generic types", () => { @ObjectType() class FriendshipEdge extends Edge(User) { @Field() - friendedAt: Date; + friendedAt!: Date; } friendshipEdgeResponse = { cursor: "friendshipCursor", @@ -339,19 +344,22 @@ describe("Generic types", () => { const recipeEdgePersonalNotesField = recipeEdgeTypeInfo.fields.find( it => it.name === "personalNotes", )!; - const recipeEdgePersonalNotesFieldType = (recipeEdgePersonalNotesField.type as IntrospectionNonNullTypeRef) - .ofType as IntrospectionObjectType; + const recipeEdgePersonalNotesFieldType = ( + recipeEdgePersonalNotesField.type as IntrospectionNonNullTypeRef + ).ofType as IntrospectionObjectType; const friendshipEdgeTypeInfo = schemaObjectTypes.find( it => it.name === "FriendshipEdge", ) as IntrospectionObjectType; const friendshipEdgeNodeField = friendshipEdgeTypeInfo.fields.find(it => it.name === "node")!; - const friendshipEdgeNodeFieldType = (friendshipEdgeNodeField.type as IntrospectionNonNullTypeRef) - .ofType as IntrospectionObjectType; + const friendshipEdgeNodeFieldType = ( + friendshipEdgeNodeField.type as IntrospectionNonNullTypeRef + ).ofType as IntrospectionObjectType; const friendshipEdgeFriendedAtField = friendshipEdgeTypeInfo.fields.find( it => it.name === "friendedAt", )!; - const friendshipEdgeFriendedAtFieldType = (friendshipEdgeFriendedAtField.type as IntrospectionNonNullTypeRef) - .ofType as IntrospectionObjectType; + const friendshipEdgeFriendedAtFieldType = ( + friendshipEdgeFriendedAtField.type as IntrospectionNonNullTypeRef + ).ofType as IntrospectionObjectType; expect(schemaObjectTypes).toHaveLength(5); // Query, User, Dog, UserCon, DogCon expect(recipeEdgeTypeInfo.fields).toHaveLength(3); @@ -363,7 +371,7 @@ describe("Generic types", () => { expect(friendshipEdgeNodeFieldType.kind).toBe(TypeKind.OBJECT); expect(friendshipEdgeNodeFieldType.name).toBe("User"); expect(friendshipEdgeFriendedAtFieldType.kind).toBe(TypeKind.SCALAR); - expect(friendshipEdgeFriendedAtFieldType.name).toBe("DateTime"); + expect(friendshipEdgeFriendedAtFieldType.name).toBe("DateTimeISO"); }); it("should return child classes data from queries", async () => { @@ -386,7 +394,7 @@ describe("Generic types", () => { } `; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); expect(result.data!.recipeEdge).toEqual(recipeEdgeResponse); expect(result.data!.friendshipEdge).toEqual({ @@ -401,11 +409,11 @@ describe("Generic types", () => { let schemaIntrospection: IntrospectionSchema; beforeAll(async () => { - function Base(TTypeClass: ClassType) { - @ObjectType({ isAbstract: true }) + function Base(TTypeClass: ClassType) { + @ObjectType() class BaseClass { - @Field(type => TTypeClass) - baseField: TType; + @Field(() => TTypeClass) + baseField!: TType; } return BaseClass; } @@ -413,21 +421,22 @@ describe("Generic types", () => { @ObjectType() class BaseSample { @Field() - sampleField: string; + sampleField!: string; } @ObjectType() class ChildSample { @Field() - sampleField: string; + sampleField!: string; + @Field() - childField: string; + childField!: string; } @ObjectType() class Child extends Base(BaseSample) { @Field() - baseField: ChildSample; // overwriting field with a up compatible type + override baseField!: ChildSample; // Overwriting field with a up compatible type } @Resolver() @@ -472,7 +481,7 @@ describe("Generic types", () => { } `; - const result = await graphql(schema, document); + const result: any = await graphql({ schema, source: document }); expect(result.data!).toEqual({ child: { diff --git a/tests/functional/interface-resolvers-args.ts b/tests/functional/interface-resolvers-args.ts index a9680b503..6946e4ca7 100644 --- a/tests/functional/interface-resolvers-args.ts +++ b/tests/functional/interface-resolvers-args.ts @@ -1,28 +1,27 @@ import "reflect-metadata"; import { - IntrospectionSchema, - IntrospectionInterfaceType, - GraphQLSchema, + type GraphQLSchema, + type IntrospectionInterfaceType, + type IntrospectionNamedTypeRef, + type IntrospectionNonNullTypeRef, + type IntrospectionSchema, graphql, - IntrospectionNonNullTypeRef, - IntrospectionNamedTypeRef, } from "graphql"; - -import { getSchemaInfo } from "../helpers/getSchemaInfo"; import { Arg, Args, ArgsType, Field, + FieldResolver, Int, InterfaceType, ObjectType, Query, Resolver, buildSchema, - FieldResolver, -} from "../../src"; -import { getMetadataStorage } from "../../src/metadata/getMetadataStorage"; +} from "type-graphql"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { getSchemaInfo } from "../helpers/getSchemaInfo"; describe("Interfaces with resolvers and arguments", () => { describe("Schema", () => { @@ -34,9 +33,10 @@ describe("Interfaces with resolvers and arguments", () => { @ArgsType() class SampleArgs1 { @Field(_type => Int) - classArg1: number; + classArg1!: number; + @Field(_type => Int) - classArg2: number; + classArg2!: number; } @InterfaceType() @@ -136,8 +136,9 @@ describe("Interfaces with resolvers and arguments", () => { sampleInterfaceWithArgsAndFieldResolver, ].forEach(type => { const sampleFieldWithArgsField = type.fields.find(it => it.name === "sampleFieldWithArgs")!; - const sampleFieldWithArgsType = (sampleFieldWithArgsField.type as IntrospectionNonNullTypeRef) - .ofType as IntrospectionNamedTypeRef; + const sampleFieldWithArgsType = ( + sampleFieldWithArgsField.type as IntrospectionNonNullTypeRef + ).ofType as IntrospectionNamedTypeRef; expect(sampleFieldWithArgsField.args).toHaveLength(1); expect(sampleFieldWithArgsType.name).toEqual("String"); @@ -156,10 +157,12 @@ describe("Interfaces with resolvers and arguments", () => { const interfaceFieldArgsTypeField = sampleInterfaceWithArgsFields.fields.find( it => it.name === "interfaceFieldArgsType", )!; - const interfaceFieldInlineArgsType = (interfaceFieldInlineArgsField.type as IntrospectionNonNullTypeRef) - .ofType as IntrospectionNamedTypeRef; - const interfaceFieldArgsTypeFieldType = (interfaceFieldArgsTypeField.type as IntrospectionNonNullTypeRef) - .ofType as IntrospectionNamedTypeRef; + const interfaceFieldInlineArgsType = ( + interfaceFieldInlineArgsField.type as IntrospectionNonNullTypeRef + ).ofType as IntrospectionNamedTypeRef; + const interfaceFieldArgsTypeFieldType = ( + interfaceFieldArgsTypeField.type as IntrospectionNonNullTypeRef + ).ofType as IntrospectionNamedTypeRef; expect(interfaceFieldInlineArgsField.args).toHaveLength(2); expect(interfaceFieldArgsTypeField.args).toHaveLength(2); @@ -174,9 +177,10 @@ describe("Interfaces with resolvers and arguments", () => { const sampleImplementingObjectWithArgsAndInheritedResolver = schemaIntrospection.types.find( type => type.name === "SampleImplementingObjectWithArgsAndInheritedResolver", ) as IntrospectionInterfaceType; - const sampleImplementingObjectWithArgsAndInheritedFieldResolver = schemaIntrospection.types.find( - type => type.name === "SampleImplementingObjectWithArgsAndInheritedFieldResolver", - ) as IntrospectionInterfaceType; + const sampleImplementingObjectWithArgsAndInheritedFieldResolver = + schemaIntrospection.types.find( + type => type.name === "SampleImplementingObjectWithArgsAndInheritedFieldResolver", + ) as IntrospectionInterfaceType; expect(sampleImplementingObjectWithArgsAndOwnResolver).toBeDefined(); expect(sampleImplementingObjectWithArgsAndInheritedResolver).toBeDefined(); expect(sampleImplementingObjectWithArgsAndInheritedFieldResolver).toBeDefined(); @@ -187,8 +191,9 @@ describe("Interfaces with resolvers and arguments", () => { sampleImplementingObjectWithArgsAndInheritedFieldResolver, ].forEach(type => { const sampleFieldWithArgsField = type.fields.find(it => it.name === "sampleFieldWithArgs")!; - const sampleFieldWithArgsType = (sampleFieldWithArgsField.type as IntrospectionNonNullTypeRef) - .ofType as IntrospectionNamedTypeRef; + const sampleFieldWithArgsType = ( + sampleFieldWithArgsField.type as IntrospectionNonNullTypeRef + ).ofType as IntrospectionNamedTypeRef; expect(sampleFieldWithArgsField.args).toHaveLength(1); expect(sampleFieldWithArgsType.name).toEqual("String"); @@ -223,7 +228,7 @@ describe("Interfaces with resolvers and arguments", () => { @ObjectType({ implements: SampleInterfaceWithArgs }) class SampleImplementingObjectWithArgsAndOwnResolver extends SampleInterfaceWithArgs { - sampleFieldWithArgs(sampleArg: string) { + override sampleFieldWithArgs(sampleArg: string) { return `SampleImplementingObjectWithArgsAndOwnResolver: ${sampleArg}`; } } @@ -254,26 +259,32 @@ describe("Interfaces with resolvers and arguments", () => { queryForSampleInterfaceWithArgs(): SampleInterfaceWithArgs { return new SampleImplementingObjectWithArgsAndOwnResolver(); } + @Query() queryForSampleInterfaceWithArgsAndInlineResolver(): SampleInterfaceWithArgsAndInlineResolver { return new SampleImplementingObjectWithArgsAndInheritedResolver(); } + @Query() queryForSampleInterfaceWithArgsAndFieldResolver(): SampleInterfaceWithArgsAndFieldResolver { return new SampleImplementingObjectWithArgsAndInheritedFieldResolver(); } + @Query() queryForSampleImplementingObjectWithArgsAndOwnResolver(): SampleImplementingObjectWithArgsAndOwnResolver { return new SampleImplementingObjectWithArgsAndOwnResolver(); } + @Query() queryForSampleImplementingObjectWithArgsAndInheritedResolver(): SampleImplementingObjectWithArgsAndInheritedResolver { return new SampleImplementingObjectWithArgsAndInheritedResolver(); } + @Query() queryForSampleImplementingObjectWithArgsAndInheritedFieldResolver(): SampleImplementingObjectWithArgsAndInheritedFieldResolver { return new SampleImplementingObjectWithArgsAndInheritedFieldResolver(); } + @Query() queryForSampleInterfaceImplementingInterfaceWithArgsAndInlineResolver(): SampleInterfaceImplementingInterfaceWithArgsAndInlineResolver { return new SampleObjectImplementingInterfaceImplementingWithArgsAndInheritedResolver(); @@ -309,10 +320,10 @@ describe("Interfaces with resolvers and arguments", () => { } `; - const { data, errors } = await graphql(schema, query); + const { data, errors } = await graphql({ schema, source: query }); expect(errors).toBeUndefined(); - const result = data!.queryForSampleInterfaceWithArgs.sampleFieldWithArgs; + const result = (data as any).queryForSampleInterfaceWithArgs.sampleFieldWithArgs; expect(result).toBeDefined(); expect(result).toEqual("SampleImplementingObjectWithArgsAndOwnResolver: sampleArgValue"); }); @@ -326,10 +337,11 @@ describe("Interfaces with resolvers and arguments", () => { } `; - const { data, errors } = await graphql(schema, query); + const { data, errors } = await graphql({ schema, source: query }); expect(errors).toBeUndefined(); - const result = data!.queryForSampleInterfaceWithArgsAndInlineResolver.sampleFieldWithArgs; + const result = (data as any).queryForSampleInterfaceWithArgsAndInlineResolver + .sampleFieldWithArgs; expect(result).toBeDefined(); expect(result).toEqual("SampleInterfaceWithArgsAndInlineResolver: sampleArgValue"); }); @@ -343,10 +355,11 @@ describe("Interfaces with resolvers and arguments", () => { } `; - const { data, errors } = await graphql(schema, query); + const { data, errors } = await graphql({ schema, source: query }); expect(errors).toBeUndefined(); - const result = data!.queryForSampleInterfaceWithArgsAndFieldResolver.sampleFieldWithArgs; + const result = (data as any).queryForSampleInterfaceWithArgsAndFieldResolver + .sampleFieldWithArgs; expect(result).toBeDefined(); expect(result).toEqual("SampleInterfaceResolver: sampleArgValue"); }); @@ -360,10 +373,10 @@ describe("Interfaces with resolvers and arguments", () => { } `; - const { data, errors } = await graphql(schema, query); + const { data, errors } = await graphql({ schema, source: query }); expect(errors).toBeUndefined(); - const result = data!.queryForSampleImplementingObjectWithArgsAndOwnResolver + const result = (data as any).queryForSampleImplementingObjectWithArgsAndOwnResolver .sampleFieldWithArgs; expect(result).toBeDefined(); expect(result).toEqual("SampleImplementingObjectWithArgsAndOwnResolver: sampleArgValue"); @@ -378,10 +391,10 @@ describe("Interfaces with resolvers and arguments", () => { } `; - const { data, errors } = await graphql(schema, query); + const { data, errors } = await graphql({ schema, source: query }); expect(errors).toBeUndefined(); - const result = data!.queryForSampleImplementingObjectWithArgsAndInheritedResolver + const result = (data as any).queryForSampleImplementingObjectWithArgsAndInheritedResolver .sampleFieldWithArgs; expect(result).toBeDefined(); expect(result).toEqual("SampleInterfaceWithArgsAndInlineResolver: sampleArgValue"); @@ -396,10 +409,10 @@ describe("Interfaces with resolvers and arguments", () => { } `; - const { data, errors } = await graphql(schema, query); + const { data, errors } = await graphql({ schema, source: query }); expect(errors).toBeUndefined(); - const result = data!.queryForSampleImplementingObjectWithArgsAndInheritedFieldResolver + const result = (data as any).queryForSampleImplementingObjectWithArgsAndInheritedFieldResolver .sampleFieldWithArgs; expect(result).toBeDefined(); expect(result).toEqual("SampleInterfaceResolver: sampleArgValue"); @@ -414,11 +427,11 @@ describe("Interfaces with resolvers and arguments", () => { } `; - const { data, errors } = await graphql(schema, query); + const { data, errors } = await graphql({ schema, source: query }); expect(errors).toBeUndefined(); - const result = data!.queryForSampleInterfaceImplementingInterfaceWithArgsAndInlineResolver - .sampleFieldWithArgs; + const result = (data as any) + .queryForSampleInterfaceImplementingInterfaceWithArgsAndInlineResolver.sampleFieldWithArgs; expect(result).toBeDefined(); expect(result).toEqual("SampleInterfaceWithArgsAndInlineResolver: sampleArgValue"); }); diff --git a/tests/functional/interfaces-and-inheritance.ts b/tests/functional/interfaces-and-inheritance.ts index a1acab0fb..4ebf7eb9d 100644 --- a/tests/functional/interfaces-and-inheritance.ts +++ b/tests/functional/interfaces-and-inheritance.ts @@ -1,35 +1,35 @@ import "reflect-metadata"; import { - IntrospectionSchema, - IntrospectionInterfaceType, - IntrospectionObjectType, - IntrospectionNonNullTypeRef, - IntrospectionNamedTypeRef, - IntrospectionInputObjectType, - GraphQLSchema, - graphql, + type GraphQLSchema, + type IntrospectionInputObjectType, + type IntrospectionInterfaceType, + type IntrospectionNamedTypeRef, + type IntrospectionNonNullTypeRef, + type IntrospectionObjectType, + type IntrospectionSchema, TypeKind, + graphql, } from "graphql"; - -import { getSchemaInfo } from "../helpers/getSchemaInfo"; -import { getInnerFieldType } from "../helpers/getInnerFieldType"; -import { getMetadataStorage } from "../../src/metadata/getMetadataStorage"; -import { GeneratingSchemaError } from "../../src/errors"; import { - InterfaceType, - ObjectType, + Arg, + Args, + ArgsType, Field, ID, - Query, - ArgsType, - Args, InputType, - Arg, - Mutation, - buildSchema, Int, + InterfaceType, + Mutation, + ObjectType, + Query, Resolver, -} from "../../src"; + buildSchema, +} from "type-graphql"; +import { GeneratingSchemaError } from "@/errors"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { expectToThrow } from "../helpers/expectToThrow"; +import { getInnerFieldType, getInnerInputFieldType } from "../helpers/getInnerFieldType"; +import { getSchemaInfo } from "../helpers/getSchemaInfo"; describe("Interfaces and inheritance", () => { describe("Schema", () => { @@ -43,94 +43,129 @@ describe("Interfaces and inheritance", () => { let sampleImplementingObject1Type: IntrospectionObjectType; let sampleImplementingObject2Type: IntrospectionObjectType; let sampleExtendingObject2Type: IntrospectionObjectType; + let sampleSecondExtendedInputType: IntrospectionInputObjectType; beforeAll(async () => { getMetadataStorage().clear(); @InterfaceType() abstract class SampleInterface1 { - @Field(type => ID) - id: string; + @Field(() => ID) + id!: string; + @Field() - interfaceStringField1: string; + interfaceStringField1!: string; } @InterfaceType() abstract class SampleInterface2 { - @Field(type => ID) - id: string; + @Field(() => ID) + id!: string; + @Field() - interfaceStringField2: string; + interfaceStringField2!: string; } @InterfaceType() abstract class SampleInterfaceExtending1 extends SampleInterface1 { @Field() - ownStringField1: string; + ownStringField1!: string; } @InterfaceType({ implements: [SampleInterface1] }) abstract class SampleInterfaceImplementing1 implements SampleInterface1 { - id: string; - interfaceStringField1: string; + id!: string; + + interfaceStringField1!: string; + @Field() - ownStringField1: string; + ownStringField1!: string; } @ObjectType({ implements: SampleInterface1 }) class SampleImplementingObject1 implements SampleInterface1 { - id: string; - interfaceStringField1: string; + id!: string; + + interfaceStringField1!: string; + @Field() - ownField1: number; + ownField1!: number; } @ObjectType({ implements: SampleInterface1 }) class SampleImplementingObject2 implements SampleInterface1 { - @Field(type => ID) - id: string; + @Field(() => ID) + id!: string; + @Field() - interfaceStringField1: string; + interfaceStringField1!: string; + @Field() - ownField2: number; + ownField2!: number; } @ObjectType({ implements: [SampleInterface1, SampleInterface2] }) class SampleMultiImplementingObject implements SampleInterface1, SampleInterface2 { - id: string; - interfaceStringField1: string; - interfaceStringField2: string; + id!: string; + + interfaceStringField1!: string; + + interfaceStringField2!: string; + @Field() - ownField3: number; + ownField3!: number; } @ObjectType({ implements: SampleInterface1 }) class SampleExtendingImplementingObject extends SampleImplementingObject2 - implements SampleInterface1 { + implements SampleInterface1 + { @Field() - ownField4: number; + ownField4!: number; } @ObjectType() class SampleExtendingObject2 extends SampleImplementingObject2 { @Field() - ownExtendingField2: number; + ownExtendingField2!: number; } @ArgsType() class SampleBaseArgs { @Field() - baseArgField: string; + baseArgField!: string; } @ArgsType() class SampleExtendingArgs extends SampleBaseArgs { @Field() - extendingArgField: boolean; + extendingArgField!: boolean; } @InputType() class SampleBaseInput { @Field() - baseInputField: string; + baseInputField!: string; } @InputType() class SampleExtendingInput extends SampleBaseInput { @Field() - extendingInputField: boolean; + extendingInputField!: boolean; + } + + // overwriting fields case + @InputType() + class SampleFirstBaseInput { + @Field() + baseField!: string; + } + @InputType() + class SampleFirstExtendedInput extends SampleFirstBaseInput { + @Field() + extendedField!: string; + } + @InputType() + class SampleSecondBaseInput { + @Field() + baseInputField!: SampleFirstBaseInput; + } + @InputType() + class SampleSecondExtendedInput extends SampleSecondBaseInput { + @Field() + override baseInputField!: SampleFirstExtendedInput; } class SampleResolver { @@ -140,12 +175,12 @@ describe("Interfaces and inheritance", () => { } @Query() - queryWithArgs(@Args() args: SampleExtendingArgs): boolean { + queryWithArgs(@Args() _args: SampleExtendingArgs): boolean { return true; } @Mutation() - mutationWithInput(@Arg("input") input: SampleExtendingInput): boolean { + mutationWithInput(@Arg("input") _input: SampleExtendingInput): boolean { return true; } } @@ -162,6 +197,7 @@ describe("Interfaces and inheritance", () => { SampleMultiImplementingObject, SampleExtendingImplementingObject, SampleExtendingObject2, + SampleSecondExtendedInput, ], }); queryType = schemaInfo.queryType; @@ -190,6 +226,9 @@ describe("Interfaces and inheritance", () => { sampleExtendingObject2Type = schemaIntrospection.types.find( type => type.name === "SampleExtendingObject2", ) as IntrospectionObjectType; + sampleSecondExtendedInputType = schemaIntrospection.types.find( + type => type.name === "SampleSecondExtendedInput", + ) as IntrospectionInputObjectType; }); // helpers @@ -203,14 +242,27 @@ describe("Interfaces and inheritance", () => { it("should generate interface type correctly", async () => { expect(sampleInterface1Type).toBeDefined(); + expect(sampleInterface2Type).toBeDefined(); expect(sampleInterface1Type.kind).toEqual(TypeKind.INTERFACE); + expect(sampleInterface2Type.kind).toEqual(TypeKind.INTERFACE); expect(sampleInterface1Type.fields).toHaveLength(2); + expect(sampleInterface2Type.fields).toHaveLength(2); - const idFieldType = getInnerFieldType(sampleInterface1Type, "id"); - const interfaceStringField = getInnerFieldType(sampleInterface1Type, "interfaceStringField1"); + const idFieldType1 = getInnerFieldType(sampleInterface1Type, "id"); + const idFieldType2 = getInnerFieldType(sampleInterface1Type, "id"); + const interfaceStringField1 = getInnerFieldType( + sampleInterface1Type, + "interfaceStringField1", + ); + const interfaceStringField2 = getInnerFieldType( + sampleInterface2Type, + "interfaceStringField2", + ); - expect(idFieldType.name).toEqual("ID"); - expect(interfaceStringField.name).toEqual("String"); + expect(idFieldType1.name).toEqual("ID"); + expect(idFieldType2.name).toEqual("ID"); + expect(interfaceStringField1.name).toEqual("String"); + expect(interfaceStringField2.name).toEqual("String"); }); it("should generate type of interface extending other interface correctly", async () => { @@ -327,7 +379,7 @@ describe("Interfaces and inheritance", () => { expect(implementedInterfaceInfo.kind).toEqual(TypeKind.INTERFACE); }); - it("should generate object type implicitly implementing mutliple interfaces correctly", async () => { + it("should generate object type implicitly implementing multiple interfaces correctly", async () => { expect(sampleMultiImplementingObjectType).toBeDefined(); expect(sampleMultiImplementingObjectType.fields).toHaveLength(4); @@ -396,23 +448,32 @@ describe("Interfaces and inheritance", () => { expect(extendingInputFieldType.name).toEqual("Boolean"); }); + it("should properly overwrite input type field", () => { + const baseInputFieldType = getInnerInputFieldType( + sampleSecondExtendedInputType, + "baseInputField", + ); + + expect(baseInputFieldType.name).toEqual("SampleFirstExtendedInput"); + }); + it("shouldn't throw error when extending wrong class type", async () => { getMetadataStorage().clear(); @InputType() class SampleInput { @Field() - inputField: string; + inputField!: string; } @ArgsType() class SampleArgs extends SampleInput { @Field() - argField: string; + argField!: string; } @Resolver() class SampleResolver { @Query() - sampleQuery(@Args() args: SampleArgs): boolean { + sampleQuery(@Args() _args: SampleArgs): boolean { return true; } } @@ -424,25 +485,74 @@ describe("Interfaces and inheritance", () => { }); }); + describe("Schema > deeply nested inheritance chain", () => { + beforeEach(() => { + getMetadataStorage().clear(); + }); + + it("should properly inherit overridden fields", async () => { + @ArgsType() + class BaseArgs { + @Field({ nullable: true }) + baseField?: string; + } + + @ArgsType() + class FirstLevelArgs extends BaseArgs { + @Field({ nullable: false }) + override baseField!: string; + } + + @ArgsType() + class SecondLevelArgs extends FirstLevelArgs { + @Field() + secondLevelField!: string; + } + + @Resolver() + class TestResolver { + @Query(() => Boolean) + testQuery(@Args() _args: SecondLevelArgs): boolean { + return true; + } + } + + const { queryType } = await getSchemaInfo({ + resolvers: [TestResolver], + }); + + const testQuery = queryType.fields.find(field => field.name === "testQuery")!; + const baseField = testQuery.args.find(arg => arg.name === "baseField")!; + expect(baseField.type).toMatchObject({ + kind: "NON_NULL", + ofType: { + kind: "SCALAR", + name: "String", + ofType: null, + }, + }); + }); + }); + describe("Errors", () => { beforeEach(() => { getMetadataStorage().clear(); }); it("should throw error when field type doesn't match with interface", async () => { - expect.assertions(3); - try { + const error = await expectToThrow(async () => { @InterfaceType() class IBase { @Field() - baseField: string; + baseField!: string; } @ObjectType({ implements: IBase }) class ChildObject implements IBase { - @Field(type => Number, { nullable: true }) - baseField: string; + @Field(() => Number, { nullable: true }) + baseField!: string; + @Field() - argField: string; + argField!: string; } class SampleResolver { @Query() @@ -450,40 +560,40 @@ describe("Interfaces and inheritance", () => { return {} as ChildObject; } } + await buildSchema({ resolvers: [SampleResolver], validate: false, }); - } catch (err) { - expect(err).toBeInstanceOf(GeneratingSchemaError); - const schemaError = err as GeneratingSchemaError; - expect(schemaError.message).toMatchInlineSnapshot(` + }); + + expect(error).toBeInstanceOf(GeneratingSchemaError); + expect(error.message).toMatchInlineSnapshot(` "Some errors occurred while generating GraphQL schema: Interface field IBase.baseField expects type String! but ChildObject.baseField is type Float. Please check the \`details\` property of the error to get more detailed info." `); - expect(JSON.stringify(schemaError.details, null, 2)).toMatchInlineSnapshot(` + expect(JSON.stringify((error as GeneratingSchemaError).details, null, 2)) + .toMatchInlineSnapshot(` "[ { - \\"message\\": \\"Interface field IBase.baseField expects type String! but ChildObject.baseField is type Float.\\" + "message": "Interface field IBase.baseField expects type String! but ChildObject.baseField is type Float." } ]" `); - } }); it("should throw error when not interface type is provided as `implements` option", async () => { - expect.assertions(2); - try { + const error = await expectToThrow(async () => { @ObjectType() class SampleNotInterface { @Field() - sampleField: string; + sampleField!: string; } @ObjectType({ implements: [SampleNotInterface] }) class SampleImplementingObject implements SampleNotInterface { @Field() - sampleField: string; + sampleField!: string; } @Resolver() class SampleResolver { @@ -492,16 +602,17 @@ describe("Interfaces and inheritance", () => { return {} as SampleImplementingObject; } } + await buildSchema({ resolvers: [SampleResolver], validate: false, }); - } catch (err) { - expect(err).toBeInstanceOf(Error); - expect(err.message).toMatchInlineSnapshot( - `"Cannot find interface type metadata for class 'SampleNotInterface' provided in 'implements' option for 'SampleImplementingObject' object type class. Please make sure that class is annotated with an '@InterfaceType()' decorator."`, - ); - } + }); + + expect(error).toBeInstanceOf(Error); + expect(error.message).toMatchInlineSnapshot( + `"Cannot find interface type metadata for class 'SampleNotInterface' provided in 'implements' option for 'SampleImplementingObject' object type class. Please make sure that class is annotated with an '@InterfaceType()' decorator."`, + ); }); }); @@ -523,49 +634,54 @@ describe("Interfaces and inheritance", () => { @ArgsType() class BaseArgs { @Field() - baseArgField: string; - @Field(type => Int, { nullable: true }) + baseArgField!: string; + + @Field(() => Int, { nullable: true }) optionalBaseArgField: number = 255; } @ArgsType() class ChildArgs extends BaseArgs { @Field() - childArgField: string; + childArgField!: string; } @InputType() class BaseInput { @Field() - baseInputField: string; - @Field(type => Int, { nullable: true }) + baseInputField!: string; + + @Field(() => Int, { nullable: true }) optionalBaseInputField: number = 255; } @InputType() class ChildInput extends BaseInput { @Field() - childInputField: string; + childInputField!: string; } @InterfaceType() abstract class BaseInterface { @Field() - baseInterfaceField: string; + baseInterfaceField!: string; @Field({ name: "renamedInterfaceField", nullable: true }) interfaceFieldToBeRenamed?: string; } @ObjectType({ implements: BaseInterface }) class FirstImplementation implements BaseInterface { - baseInterfaceField: string; + baseInterfaceField!: string; + interfaceFieldToBeRenamed?: string; + @Field() - firstField: string; + firstField!: string; } @ObjectType({ implements: BaseInterface }) class SecondImplementation implements BaseInterface { - baseInterfaceField: string; + baseInterfaceField!: string; + @Field() - secondField: string; + secondField!: string; } @InterfaceType({ @@ -576,52 +692,58 @@ describe("Interfaces and inheritance", () => { if ("secondField" in value) { return "SecondInterfaceWithStringResolveTypeObject"; } - return; + return undefined; }, }) abstract class InterfaceWithStringResolveType { @Field() - baseInterfaceField: string; + baseInterfaceField!: string; } @ObjectType({ implements: InterfaceWithStringResolveType }) class FirstInterfaceWithStringResolveTypeObject implements InterfaceWithStringResolveType { - baseInterfaceField: string; + baseInterfaceField!: string; + @Field() - firstField: string; + firstField!: string; } @ObjectType({ implements: InterfaceWithStringResolveType }) class SecondInterfaceWithStringResolveTypeObject implements InterfaceWithStringResolveType { - baseInterfaceField: string; + baseInterfaceField!: string; + @Field() - secondField: string; + secondField!: string; } @InterfaceType({ resolveType: value => { if ("firstField" in value) { + // eslint-disable-next-line @typescript-eslint/no-use-before-define return FirstInterfaceWithClassResolveTypeObject; } if ("secondField" in value) { + // eslint-disable-next-line @typescript-eslint/no-use-before-define return SecondInterfaceWithClassResolveTypeObject; } - return; + return undefined; }, }) abstract class InterfaceWithClassResolveType { @Field() - baseInterfaceField: string; + baseInterfaceField!: string; } @ObjectType({ implements: InterfaceWithClassResolveType }) class FirstInterfaceWithClassResolveTypeObject implements InterfaceWithClassResolveType { - baseInterfaceField: string; + baseInterfaceField!: string; + @Field() - firstField: string; + firstField!: string; } @ObjectType({ implements: InterfaceWithClassResolveType }) class SecondInterfaceWithClassResolveTypeObject implements InterfaceWithClassResolveType { - baseInterfaceField: string; + baseInterfaceField!: string; + @Field() - secondField: string; + secondField!: string; } class SampleBaseClass { @@ -632,17 +754,39 @@ describe("Interfaces and inheritance", () => { @ObjectType() class SampleExtendingNormalClassObject extends SampleBaseClass { @Field() - sampleField: string; + sampleField!: string; } @InputType() class SampleExtendingNormalClassInput extends SampleBaseClass { @Field() - sampleField: string; + sampleField!: string; } @ArgsType() class SampleExtendingNormalClassArgs extends SampleBaseClass { @Field() - sampleField: string; + sampleField!: string; + } + + // overwriting fields case + @InputType() + class SampleFirstBaseInput { + @Field() + baseField!: string; + } + @InputType() + class SampleFirstExtendedInput extends SampleFirstBaseInput { + @Field() + extendedField!: string; + } + @InputType() + class SampleSecondBaseInput { + @Field() + baseInputField!: SampleFirstBaseInput; + } + @InputType() + class SampleSecondExtendedInput extends SampleSecondBaseInput { + @Field() + override baseInputField!: SampleFirstExtendedInput; } @Resolver() @@ -719,6 +863,12 @@ describe("Interfaces and inheritance", () => { obj.interfaceFieldToBeRenamed = "interfaceFieldToBeRenamed"; return obj; } + + @Mutation() + overwritingInputFieldMutation(@Arg("input") input: SampleSecondExtendedInput): boolean { + mutationInput = input; + return true; + } } schema = await buildSchema({ @@ -741,8 +891,8 @@ describe("Interfaces and inheritance", () => { } }`; - const result = await graphql(schema, query); - const data = result.data!.getFirstInterfaceImplementationObject; + const result: any = await graphql({ schema, source: query }); + const data = result.data.getFirstInterfaceImplementationObject; expect(data.baseInterfaceField).toEqual("baseInterfaceField"); }); @@ -759,8 +909,8 @@ describe("Interfaces and inheritance", () => { } }`; - const result = await graphql(schema, query); - const data = result.data!.getFirstInterfaceImplementationObject; + const result: any = await graphql({ schema, source: query }); + const data = result.data.getFirstInterfaceImplementationObject; expect(data.baseInterfaceField).toEqual("baseInterfaceField"); expect(data.firstField).toEqual("firstField"); expect(data.secondField).toBeUndefined(); @@ -779,8 +929,8 @@ describe("Interfaces and inheritance", () => { } }`; - const result = await graphql(schema, query); - const data = result.data!.getSecondInterfaceWithStringResolveTypeObject; + const result: any = await graphql({ schema, source: query }); + const data = result.data.getSecondInterfaceWithStringResolveTypeObject; expect(data.baseInterfaceField).toEqual("baseInterfaceField"); expect(data.firstField).toBeUndefined(); expect(data.secondField).toEqual("secondField"); @@ -799,8 +949,8 @@ describe("Interfaces and inheritance", () => { } }`; - const result = await graphql(schema, query); - const data = result.data!.getSecondInterfaceWithClassResolveTypeObject; + const result: any = await graphql({ schema, source: query }); + const data = result.data.getSecondInterfaceWithClassResolveTypeObject; expect(data.baseInterfaceField).toEqual("baseInterfaceField"); expect(data.firstField).toBeUndefined(); expect(data.secondField).toEqual("secondField"); @@ -820,10 +970,10 @@ describe("Interfaces and inheritance", () => { } }`; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); expect(result.errors?.[0]?.message).toMatchInlineSnapshot( - `"Abstract type \\"InterfaceWithClassResolveType\\" must resolve to an Object type at runtime for field \\"Query.notMatchingValueForInterfaceWithClassResolveTypeObject\\". Either the \\"InterfaceWithClassResolveType\\" type should provide a \\"resolveType\\" function or each possible type should provide an \\"isTypeOf\\" function."`, + `"Abstract type "InterfaceWithClassResolveType" must resolve to an Object type at runtime for field "Query.notMatchingValueForInterfaceWithClassResolveTypeObject". Either the "InterfaceWithClassResolveType" type should provide a "resolveType" function or each possible type should provide an "isTypeOf" function."`, ); }); @@ -834,7 +984,7 @@ describe("Interfaces and inheritance", () => { } }`; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); expect(result.data).toBeNull(); expect(result.errors).toHaveLength(1); @@ -856,8 +1006,8 @@ describe("Interfaces and inheritance", () => { } }`; - const result = await graphql(schema, query); - const data = result.data!.getFirstInterfaceImplementationObject; + const result: any = await graphql({ schema, source: query }); + const data = result.data.getFirstInterfaceImplementationObject; expect(data.baseInterfaceField).toEqual("baseInterfaceField"); expect(data.firstField).toEqual("firstField"); }); @@ -869,10 +1019,10 @@ describe("Interfaces and inheritance", () => { } }`; - const { data, errors } = await graphql(schema, query); + const { data, errors } = await graphql({ schema, source: query }); expect(errors).toBeUndefined(); - expect(data!.renamedFieldInterfaceQuery.renamedInterfaceField).toEqual( + expect((data as any).renamedFieldInterfaceQuery.renamedInterfaceField).toEqual( "interfaceFieldToBeRenamed", ); }); @@ -885,7 +1035,7 @@ describe("Interfaces and inheritance", () => { ) }`; - await graphql(schema, query); + await graphql({ schema, source: query }); expect(queryArgs.baseArgField).toEqual("baseArgField"); expect(queryArgs.childArgField).toEqual("childArgField"); @@ -900,7 +1050,7 @@ describe("Interfaces and inheritance", () => { }) }`; - await graphql(schema, query); + await graphql({ schema, source: query }); expect(mutationInput.baseInputField).toEqual("baseInputField"); expect(mutationInput.childInputField).toEqual("childInputField"); @@ -915,14 +1065,35 @@ describe("Interfaces and inheritance", () => { ) }`; - const { data } = await graphql(schema, query); + const { data } = await graphql({ schema, source: query }); - expect(data!.baseClassQuery).toEqual("sampleStaticMethod"); + expect((data as any).baseClassQuery).toEqual("sampleStaticMethod"); expect(inputFieldValue).toEqual("sampleInputValue"); expect(argsFieldValue).toEqual("sampleArgValue"); }); it("should allow to return plain object when return type is a class that implements an interface", async () => { + const query = `mutation { + overwritingInputFieldMutation(input: { + baseInputField: { + baseField: "baseField", + extendedField: "extendedField", + } + }) + }`; + + const { errors } = await graphql({ schema, source: query }); + + expect(errors).toBeUndefined(); + expect(mutationInput).toEqual({ + baseInputField: { + baseField: "baseField", + extendedField: "extendedField", + }, + }); + }); + + it("should correctly transform data of overwritten input field", async () => { const query = `query { secondImplementationPlainQuery { baseInterfaceField @@ -930,11 +1101,13 @@ describe("Interfaces and inheritance", () => { } }`; - const { data, errors } = await graphql(schema, query); + const { data, errors } = await graphql({ schema, source: query }); expect(errors).toBeUndefined(); - expect(data!.secondImplementationPlainQuery.baseInterfaceField).toEqual("baseInterfaceField"); - expect(data!.secondImplementationPlainQuery.secondField).toEqual("secondField"); + expect((data as any).secondImplementationPlainQuery.baseInterfaceField).toEqual( + "baseInterfaceField", + ); + expect((data as any).secondImplementationPlainQuery.secondField).toEqual("secondField"); }); }); @@ -947,21 +1120,21 @@ describe("Interfaces and inheritance", () => { @InterfaceType() class BaseInterface { @Field() - baseField: string; + baseField!: string; } @ObjectType({ implements: [BaseInterface] }) class One extends BaseInterface { @Field() - one: string; + one!: string; } @ObjectType({ implements: [BaseInterface] }) class Two extends BaseInterface { @Field() - two: string; + two!: string; } @Resolver() class OneTwoResolver { - @Query(returns => BaseInterface) + @Query(() => BaseInterface) base(): BaseInterface { const one = new One(); one.baseField = "baseField"; @@ -994,8 +1167,8 @@ describe("Interfaces and inheritance", () => { orphanedTypes: [One, Two], validate: false, }); - const firstResult = await graphql(firstSchema, query); - const secondResult = await graphql(secondSchema, query); + const firstResult = await graphql({ schema: firstSchema, source: query }); + const secondResult = await graphql({ schema: secondSchema, source: query }); expect(firstResult.errors).toBeUndefined(); expect(firstResult.data!.base).toEqual({ @@ -1020,26 +1193,26 @@ describe("Interfaces and inheritance", () => { if ("two" in value) { return "Two"; } - throw new Error("Unkown resolveType error"); + throw new Error("Unknown resolveType error"); }, }) class BaseInterface { @Field() - baseField: string; + baseField!: string; } @ObjectType({ implements: [BaseInterface] }) class One extends BaseInterface { @Field() - one: string; + one!: string; } @ObjectType({ implements: [BaseInterface] }) class Two extends BaseInterface { @Field() - two: string; + two!: string; } @Resolver() class OneTwoResolver { - @Query(returns => BaseInterface) + @Query(() => BaseInterface) base(): BaseInterface { const one = new One(); one.baseField = "baseField"; @@ -1072,8 +1245,8 @@ describe("Interfaces and inheritance", () => { orphanedTypes: [One, Two], validate: false, }); - const firstResult = await graphql(firstSchema, query); - const secondResult = await graphql(secondSchema, query); + const firstResult = await graphql({ schema: firstSchema, source: query }); + const secondResult = await graphql({ schema: secondSchema, source: query }); expect(firstResult.errors).toBeUndefined(); expect(firstResult.data!.base).toEqual({ @@ -1093,31 +1266,33 @@ describe("Interfaces and inheritance", () => { @InterfaceType({ resolveType: value => { if ("one" in value) { + // eslint-disable-next-line @typescript-eslint/no-use-before-define return One; } if ("two" in value) { + // eslint-disable-next-line @typescript-eslint/no-use-before-define return Two; } - throw new Error("Unkown resolveType error"); + throw new Error("Unknown resolveType error"); }, }) class BaseInterface { @Field() - baseField: string; + baseField!: string; } @ObjectType({ implements: [BaseInterface] }) class One extends BaseInterface { @Field() - one: string; + one!: string; } @ObjectType({ implements: [BaseInterface] }) class Two extends BaseInterface { @Field() - two: string; + two!: string; } @Resolver() class OneTwoResolver { - @Query(returns => BaseInterface) + @Query(() => BaseInterface) base(): BaseInterface { const one = new One(); one.baseField = "baseField"; @@ -1150,8 +1325,8 @@ describe("Interfaces and inheritance", () => { orphanedTypes: [One, Two], validate: false, }); - const firstResult = await graphql(firstSchema, query); - const secondResult = await graphql(secondSchema, query); + const firstResult = await graphql({ schema: firstSchema, source: query }); + const secondResult = await graphql({ schema: secondSchema, source: query }); expect(firstResult.errors).toBeUndefined(); expect(firstResult.data!.base).toEqual({ @@ -1171,26 +1346,29 @@ describe("Interfaces and inheritance", () => { @InterfaceType() abstract class SampleUnusedInterface { @Field() - sampleField: string; + sampleField!: string; } @ObjectType({ implements: SampleUnusedInterface }) + // eslint-disable-next-line @typescript-eslint/no-unused-vars class SampleUnusedObjectType implements SampleUnusedInterface { @Field() - sampleField: string; + sampleField!: string; + @Field() - sampleUnusedInterfaceField: SampleUnusedInterface; + sampleUnusedInterfaceField!: SampleUnusedInterface; } @InterfaceType() abstract class SampleUsedInterface { @Field() - sampleField: string; + sampleField!: string; } @ObjectType({ implements: SampleUsedInterface }) class SampleObjectTypeImplementingUsedInterface implements SampleUsedInterface { @Field() - sampleField: string; + sampleField!: string; + @Field() - sampleAdditionalField: string; + sampleAdditionalField!: string; } @Resolver() class SampleResolver { @@ -1222,24 +1400,25 @@ describe("Interfaces and inheritance", () => { }); it("should by default automatically register all and only the object types that implements an interface type used as field type", async () => { - getMetadataStorage().clear(); @InterfaceType() class IFooBar { @Field(() => String) - fooBarKind: string; + fooBarKind!: string; } @ObjectType({ implements: IFooBar }) + // eslint-disable-next-line @typescript-eslint/no-unused-vars class Foo extends IFooBar { - fooBarKind = "Foo"; + override fooBarKind = "Foo"; } @ObjectType({ implements: IFooBar }) + // eslint-disable-next-line @typescript-eslint/no-unused-vars class Bar extends IFooBar { - fooBarKind = "Bar"; + override fooBarKind = "Bar"; } @ObjectType() class FooBar { @Field(() => IFooBar) - iFooBarField: IFooBar; + iFooBarField!: IFooBar; } @Resolver() class TestResolver { @@ -1276,21 +1455,24 @@ describe("Interfaces and inheritance", () => { @InterfaceType({ autoRegisterImplementations: false }) abstract class SampleUsedInterface { @Field() - sampleField: string; + sampleField!: string; } @ObjectType({ implements: SampleUsedInterface }) class FirstSampleObject implements SampleUsedInterface { @Field() - sampleField: string; + sampleField!: string; + @Field() - sampleFirstAdditionalField: string; + sampleFirstAdditionalField!: string; } @ObjectType({ implements: SampleUsedInterface }) + // eslint-disable-next-line @typescript-eslint/no-unused-vars class SecondSampleObject implements SampleUsedInterface { @Field() - sampleField: string; + sampleField!: string; + @Field() - sampleSecondAdditionalField: string; + sampleSecondAdditionalField!: string; } @Resolver() class SampleResolver { diff --git a/tests/functional/ioc-container.ts b/tests/functional/ioc-container.ts index 054c1473a..16d34afa0 100644 --- a/tests/functional/ioc-container.ts +++ b/tests/functional/ioc-container.ts @@ -1,18 +1,17 @@ import "reflect-metadata"; import { graphql } from "graphql"; -import { Container, Service } from "typedi"; - -import { getMetadataStorage } from "../../src/metadata/getMetadataStorage"; import { - ObjectType, + Arg, + type ContainerType, Field, - Resolver, + ObjectType, Query, - Arg, + Resolver, + type ResolverData, buildSchema, - ResolverData, - ContainerType, -} from "../../src"; +} from "type-graphql"; +import { Container, Service } from "typedi"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; describe("IOC container", () => { beforeEach(() => { @@ -33,9 +32,10 @@ describe("IOC container", () => { field?: string; } @Service() - @Resolver(of => SampleObject) + @Resolver(() => SampleObject) class SampleResolver { constructor(private service: SampleService) {} + @Query() sampleQuery(): SampleObject { serviceValue = this.service.value; @@ -54,7 +54,7 @@ describe("IOC container", () => { } } `; - await graphql(schema, query); + await graphql({ schema, source: query }); expect(serviceValue).toEqual(initValue); }); @@ -66,9 +66,10 @@ describe("IOC container", () => { @Field({ nullable: true }) field?: string; } - @Resolver(of => SampleObject) + @Resolver(() => SampleObject) class SampleResolver { value = Math.random(); + @Query() sampleQuery(): SampleObject { resolverValue = this.value; @@ -86,10 +87,10 @@ describe("IOC container", () => { } } `; - await graphql(schema, query); + await graphql({ schema, source: query }); const firstCallValue = resolverValue; resolverValue = undefined; - await graphql(schema, query); + await graphql({ schema, source: query }); const secondCallValue = resolverValue; expect(firstCallValue).toBeDefined(); @@ -126,12 +127,12 @@ describe("IOC container", () => { `; const requestId = Math.random(); - await graphql(schema, query, null, { requestId }); + await graphql({ schema, source: query, contextValue: { requestId } }); expect(contextRequestId).toEqual(requestId); }); it("should properly get container from container getter function", async () => { - let called: boolean = false; + let called = false; @Resolver() class SampleResolver { @@ -166,13 +167,13 @@ describe("IOC container", () => { container: mockedContainer, }; - await graphql(schema, query, null, queryContext); + await graphql({ schema, source: query, contextValue: queryContext }); expect(called).toEqual(true); }); it("should properly get instance from an async container", async () => { - let called: boolean = false; + let called = false; @Service() @Resolver() @@ -202,7 +203,7 @@ describe("IOC container", () => { } `; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); expect(result.errors).toBeUndefined(); expect(result.data!.sampleQuery).toEqual("sampleArgValue"); diff --git a/tests/functional/manual-decorators.ts b/tests/functional/manual-decorators.ts index 00d8ef419..b5ea1a90a 100644 --- a/tests/functional/manual-decorators.ts +++ b/tests/functional/manual-decorators.ts @@ -1,6 +1,6 @@ import "reflect-metadata"; -import { IntrospectionObjectType } from "graphql"; -import { Args, ArgsType, Field, ObjectType, Query, Resolver } from "../../src"; +import { type IntrospectionObjectType } from "graphql"; +import { Args, ArgsType, Field, ObjectType, Query, Resolver } from "type-graphql"; import { getSchemaInfo } from "../helpers/getSchemaInfo"; describe("manual decorators", () => { @@ -8,17 +8,17 @@ describe("manual decorators", () => { @ObjectType() class SampleObject { @Field() - manualField: string; + manualField!: string; } - // dynamically register field + // Dynamically register field Field(() => String)(SampleObject.prototype, "dynamicField"); @ArgsType() class SampleArgs { @Field() - sampleField: string; + sampleField!: string; } - // dynamically register field args + // Dynamically register field args Args(() => SampleArgs)(SampleObject.prototype, "dynamicField", 0); @Resolver() @@ -29,7 +29,7 @@ describe("manual decorators", () => { } } - // get builded schema info from retrospection + // Get builded schema info from retrospection const schemaInfo = await getSchemaInfo({ resolvers: [SampleResolver], }); @@ -51,7 +51,9 @@ describe("manual decorators", () => { expect(dynamicField.args).toEqual([ { defaultValue: null, + deprecationReason: null, description: null, + isDeprecated: false, name: "sampleField", type: { kind: "NON_NULL", diff --git a/tests/functional/metadata-storage.ts b/tests/functional/metadata-storage.ts index a2aed7bc4..f7fd3f0d8 100644 --- a/tests/functional/metadata-storage.ts +++ b/tests/functional/metadata-storage.ts @@ -1,17 +1,17 @@ import "reflect-metadata"; - -import { getMetadataStorage } from "../../src/metadata/getMetadataStorage"; +import { createPubSub } from "@graphql-yoga/subscription"; import { - Resolver, - Query, - buildSchema, - Mutation, - Subscription, + type ClassType, + Field, FieldResolver, + Mutation, ObjectType, - ClassType, - Field, -} from "../../src"; + Query, + Resolver, + Subscription, + buildSchema, +} from "type-graphql"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; describe("MetadataStorage", () => { describe("resolvers inheritance", () => { @@ -24,7 +24,7 @@ describe("MetadataStorage", () => { getMetadataStorage().clear(); function createAbstractResolver(classType: ClassType) { - @Resolver(() => classType, { isAbstract: true }) + @Resolver(() => classType) abstract class AbstractResolver { @Query({ name: INHERITED_QUERY_NAME }) abstractQuery(): boolean { @@ -52,10 +52,10 @@ describe("MetadataStorage", () => { @ObjectType() class SampleObject { @Field() - sampleField: boolean; + sampleField!: boolean; @Field({ name: INHERITED_FIELD_RESOLVER_NAME }) - abstractSampleField: boolean; + abstractSampleField!: boolean; } @Resolver(() => SampleObject) @@ -81,7 +81,10 @@ describe("MetadataStorage", () => { } } - await buildSchema({ resolvers: [SubClassResolver] }); + await buildSchema({ + resolvers: [SubClassResolver], + pubSub: createPubSub(), + }); }); it("should not have duplicated query metadata for inherited resolvers", async () => { diff --git a/tests/functional/middlewares.ts b/tests/functional/middlewares.ts index cc170d05b..ad1124bce 100644 --- a/tests/functional/middlewares.ts +++ b/tests/functional/middlewares.ts @@ -1,32 +1,30 @@ import "reflect-metadata"; -import { GraphQLSchema, graphql } from "graphql"; - -import { getMetadataStorage } from "../../src/metadata/getMetadataStorage"; +import { type GraphQLSchema, graphql } from "graphql"; import { + Arg, Field, + FieldResolver, + type MiddlewareFn, + type MiddlewareInterface, + type NextFn, ObjectType, - Ctx, - Authorized, Query, Resolver, - buildSchema, - FieldResolver, - UnauthorizedError, - ForbiddenError, - MiddlewareFn, + type ResolverData, UseMiddleware, - Arg, - MiddlewareInterface, - NextFn, - ResolverData, -} from "../../src"; -import { createMethodDecorator } from "../../src/decorators/createMethodDecorator"; + buildSchema, +} from "type-graphql"; +import { createMethodDecorator } from "@/decorators/createMethodDecorator"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; describe("Middlewares", () => { let schema: GraphQLSchema; let sampleResolver: any; let middlewareLogs: string[] = []; - const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); + const sleep = (time: number) => + new Promise(resolve => { + setTimeout(resolve, time); + }); beforeEach(() => { middlewareLogs = []; @@ -35,71 +33,73 @@ describe("Middlewares", () => { beforeAll(async () => { getMetadataStorage().clear(); - const middleware1: MiddlewareFn = async ({}, next) => { + const middleware1: MiddlewareFn = async (_, next) => { middlewareLogs.push("middleware1 before"); const result = await next(); middlewareLogs.push("middleware1 after"); return result; }; - const middleware2: MiddlewareFn = async ({}, next) => { + const middleware2: MiddlewareFn = async (_, next) => { middlewareLogs.push("middleware2 before"); const result = await next(); middlewareLogs.push("middleware2 after"); return result; }; - const middleware3: MiddlewareFn = async ({}, next) => { + const middleware3: MiddlewareFn = async (_, next) => { middlewareLogs.push("middleware3 before"); const result = await next(); middlewareLogs.push("middleware3 after"); return result; }; - const interceptMiddleware: MiddlewareFn = async ({}, next) => { + const interceptMiddleware: MiddlewareFn = async (_, next) => { const result = await next(); middlewareLogs.push(result); return "interceptMiddleware"; }; - const returnUndefinedMiddleware: MiddlewareFn = async ({}, next) => { + const returnUndefinedMiddleware: MiddlewareFn = async (_, next) => { const result = await next(); middlewareLogs.push(result); }; - const errorCatchMiddleware: MiddlewareFn = async ({}, next) => { + const errorCatchMiddleware: MiddlewareFn = async (_, next) => { try { - return await next(); + const result = await next(); + return result; } catch (err) { - middlewareLogs.push(err.message); + middlewareLogs.push((err as Error).message); return "errorCatchMiddleware"; } }; - const errorThrowAfterMiddleware: MiddlewareFn = async ({}, next) => { + const errorThrowAfterMiddleware: MiddlewareFn = async (_, next) => { await next(); middlewareLogs.push("errorThrowAfterMiddleware"); throw new Error("errorThrowAfterMiddleware"); }; - const errorThrowMiddleware: MiddlewareFn = async ({}, next) => { + const errorThrowMiddleware: MiddlewareFn = async _ => { middlewareLogs.push("errorThrowMiddleware"); throw new Error("errorThrowMiddleware"); }; - const fieldResolverMiddleware: MiddlewareFn = async ({}, next) => { + const fieldResolverMiddleware: MiddlewareFn = async (_, next) => { middlewareLogs.push("fieldResolverMiddlewareBefore"); const result = await next(); middlewareLogs.push("fieldResolverMiddlewareAfter"); return result; }; - const doubleNextMiddleware: MiddlewareFn = async ({}, next) => { + const doubleNextMiddleware: MiddlewareFn = async (_, next) => { const result1 = await next(); - const result2 = await next(); + await next(); return result1; }; class ClassMiddleware implements MiddlewareInterface { private logName = "ClassMiddleware"; - async use(action: ResolverData, next: NextFn) { + + async use(_: ResolverData, next: NextFn) { middlewareLogs.push(`${this.logName} before`); const result = await next(); middlewareLogs.push(`${this.logName} after`); return result; } } - const CustomMethodDecorator = createMethodDecorator(async (resolverData, next) => { + const CustomMethodDecorator = createMethodDecorator(async (_, next) => { middlewareLogs.push("CustomMethodDecorator"); return next(); }); @@ -107,17 +107,17 @@ describe("Middlewares", () => { @ObjectType() class SampleObject { @Field() - normalField: string; + normalField!: string; @Field() - resolverField: string; + resolverField!: string; @Field() @UseMiddleware(fieldResolverMiddleware) - middlewareField: string; + middlewareField!: string; } - @Resolver(of => SampleObject) + @Resolver(() => SampleObject) class SampleResolver { @Query() normalQuery(): boolean { @@ -132,7 +132,7 @@ describe("Middlewares", () => { } as SampleObject; } - @Query(returns => String) + @Query(() => String) @UseMiddleware(middleware1, middleware2, middleware3) async middlewareOrderQuery() { middlewareLogs.push("middlewareOrderQuery"); @@ -143,7 +143,7 @@ describe("Middlewares", () => { @UseMiddleware(middleware1) @UseMiddleware(middleware2) @UseMiddleware(middleware3) - @Query(returns => String) + @Query(() => String) async multipleMiddlewareDecoratorsQuery() { middlewareLogs.push("multipleMiddlewareDecoratorsQuery"); return "multipleMiddlewareDecoratorsQueryResult"; @@ -235,9 +235,9 @@ describe("Middlewares", () => { normalQuery }`; - const { data } = await graphql(schema, query); + const { data } = await graphql({ schema, source: query }); - expect(data!.normalQuery).toEqual(true); + expect((data as any).normalQuery).toEqual(true); }); it("should correctly call middlewares in order", async () => { @@ -245,9 +245,9 @@ describe("Middlewares", () => { middlewareOrderQuery }`; - const { data } = await graphql(schema, query); + const { data } = await graphql({ schema, source: query }); - expect(data!.middlewareOrderQuery).toEqual("middlewareOrderQueryResult"); + expect((data as any).middlewareOrderQuery).toEqual("middlewareOrderQueryResult"); expect(middlewareLogs).toHaveLength(7); expect(middlewareLogs[0]).toEqual("middleware1 before"); @@ -264,9 +264,9 @@ describe("Middlewares", () => { multipleMiddlewareDecoratorsQuery }`; - const { data } = await graphql(schema, query); + const { data } = await graphql({ schema, source: query }); - expect(data!.multipleMiddlewareDecoratorsQuery).toEqual( + expect((data as any).multipleMiddlewareDecoratorsQuery).toEqual( "multipleMiddlewareDecoratorsQueryResult", ); @@ -285,9 +285,9 @@ describe("Middlewares", () => { middlewareInterceptQuery }`; - const { data } = await graphql(schema, query); + const { data } = await graphql({ schema, source: query }); - expect(data!.middlewareInterceptQuery).toEqual("interceptMiddleware"); + expect((data as any).middlewareInterceptQuery).toEqual("interceptMiddleware"); expect(middlewareLogs).toHaveLength(2); expect(middlewareLogs[0]).toEqual("middlewareInterceptQuery"); expect(middlewareLogs[1]).toEqual("middlewareInterceptQueryResult"); @@ -298,9 +298,11 @@ describe("Middlewares", () => { middlewareReturnUndefinedQuery }`; - const { data } = await graphql(schema, query); + const { data } = await graphql({ schema, source: query }); - expect(data!.middlewareReturnUndefinedQuery).toEqual("middlewareReturnUndefinedQueryResult"); + expect((data as any).middlewareReturnUndefinedQuery).toEqual( + "middlewareReturnUndefinedQueryResult", + ); expect(middlewareLogs).toHaveLength(4); expect(middlewareLogs[0]).toEqual("middlewareReturnUndefinedQuery"); expect(middlewareLogs[1]).toEqual("middlewareReturnUndefinedQueryResult"); @@ -313,9 +315,9 @@ describe("Middlewares", () => { middlewareErrorCatchQuery(throwError: true) }`; - const { data } = await graphql(schema, query); + const { data } = await graphql({ schema, source: query }); - expect(data!.middlewareErrorCatchQuery).toEqual("errorCatchMiddleware"); + expect((data as any).middlewareErrorCatchQuery).toEqual("errorCatchMiddleware"); expect(middlewareLogs).toHaveLength(2); expect(middlewareLogs[0]).toEqual("middlewareErrorCatchQuery"); expect(middlewareLogs[1]).toEqual("middlewareErrorCatchQueryError"); @@ -326,9 +328,9 @@ describe("Middlewares", () => { middlewareErrorCatchQuery(throwError: false) }`; - const { data } = await graphql(schema, query); + const { data } = await graphql({ schema, source: query }); - expect(data!.middlewareErrorCatchQuery).toEqual("middlewareErrorCatchQueryResult"); + expect((data as any).middlewareErrorCatchQuery).toEqual("middlewareErrorCatchQueryResult"); }); it("should propagate thrown error up to graphql handler", async () => { @@ -336,7 +338,7 @@ describe("Middlewares", () => { middlewareThrowErrorAfterQuery }`; - const { errors } = await graphql(schema, query); + const { errors } = await graphql({ schema, source: query }); expect(errors).toHaveLength(1); expect(errors![0].message).toEqual("errorThrowAfterMiddleware"); @@ -350,7 +352,7 @@ describe("Middlewares", () => { middlewareThrowErrorQuery }`; - const { errors } = await graphql(schema, query); + const { errors } = await graphql({ schema, source: query }); expect(errors).toHaveLength(1); expect(errors![0].message).toEqual("errorThrowMiddleware"); @@ -365,9 +367,9 @@ describe("Middlewares", () => { } }`; - const { data } = await graphql(schema, query); + const { data } = await graphql({ schema, source: query }); - expect(data!.sampleObjectQuery.resolverField).toEqual("resolverField"); + expect((data as any).sampleObjectQuery.resolverField).toEqual("resolverField"); expect(middlewareLogs).toHaveLength(3); expect(middlewareLogs[0]).toEqual("fieldResolverMiddlewareBefore"); expect(middlewareLogs[1]).toEqual("resolverField"); @@ -379,9 +381,9 @@ describe("Middlewares", () => { classMiddlewareQuery }`; - const { data } = await graphql(schema, query); + const { data } = await graphql({ schema, source: query }); - expect(data!.classMiddlewareQuery).toEqual("classMiddlewareQueryResult"); + expect((data as any).classMiddlewareQuery).toEqual("classMiddlewareQueryResult"); expect(middlewareLogs).toHaveLength(3); expect(middlewareLogs[0]).toEqual("ClassMiddleware before"); expect(middlewareLogs[1]).toEqual("classMiddlewareQuery"); @@ -393,9 +395,9 @@ describe("Middlewares", () => { customMethodDecoratorQuery }`; - const { data } = await graphql(schema, query); + const { data } = await graphql({ schema, source: query }); - expect(data!.customMethodDecoratorQuery).toEqual("customMethodDecoratorQuery"); + expect((data as any).customMethodDecoratorQuery).toEqual("customMethodDecoratorQuery"); expect(middlewareLogs).toHaveLength(2); expect(middlewareLogs[0]).toEqual("CustomMethodDecorator"); expect(middlewareLogs[1]).toEqual("customMethodDecoratorQuery"); @@ -408,9 +410,9 @@ describe("Middlewares", () => { } }`; - const { data } = await graphql(schema, query); + const { data } = await graphql({ schema, source: query }); - expect(data!.sampleObjectQuery.middlewareField).toEqual("middlewareField"); + expect((data as any).sampleObjectQuery.middlewareField).toEqual("middlewareField"); expect(middlewareLogs).toHaveLength(2); expect(middlewareLogs[0]).toEqual("fieldResolverMiddlewareBefore"); expect(middlewareLogs[1]).toEqual("fieldResolverMiddlewareAfter"); @@ -421,20 +423,20 @@ describe("Middlewares", () => { doubleNextMiddlewareQuery }`; - const { errors } = await graphql(schema, query); + const { errors } = await graphql({ schema, source: query }); expect(errors).toHaveLength(1); expect(errors![0].message).toEqual("next() called multiple times"); }); it("should correctly call global middlewares before local ones", async () => { - const globalMiddleware1: MiddlewareFn = async ({}, next) => { + const globalMiddleware1: MiddlewareFn = async (_, next) => { middlewareLogs.push("globalMiddleware1 before"); const result = await next(); middlewareLogs.push("globalMiddleware1 after"); return result; }; - const globalMiddleware2: MiddlewareFn = async ({}, next) => { + const globalMiddleware2: MiddlewareFn = async (_, next) => { middlewareLogs.push("globalMiddleware2 before"); const result = await next(); middlewareLogs.push("globalMiddleware2 after"); @@ -448,9 +450,9 @@ describe("Middlewares", () => { middlewareOrderQuery }`; - const { data } = await graphql(localSchema, query); + const { data } = await graphql({ schema: localSchema, source: query }); - expect(data!.middlewareOrderQuery).toEqual("middlewareOrderQueryResult"); + expect((data as any).middlewareOrderQuery).toEqual("middlewareOrderQueryResult"); expect(middlewareLogs).toHaveLength(11); expect(middlewareLogs[0]).toEqual("globalMiddleware1 before"); expect(middlewareLogs[1]).toEqual("globalMiddleware2 before"); diff --git a/tests/functional/nested-interface-inheritance.ts b/tests/functional/nested-interface-inheritance.ts new file mode 100644 index 000000000..1f132890e --- /dev/null +++ b/tests/functional/nested-interface-inheritance.ts @@ -0,0 +1,76 @@ +import "reflect-metadata"; +import { type GraphQLSchema, printSchema } from "graphql"; +import { Field, InterfaceType, ObjectType, Query, Resolver } from "../../src"; +import { getSchemaInfo } from "../helpers/getSchemaInfo"; + +describe("nested interface inheritance", () => { + let schema: GraphQLSchema; + beforeAll(async () => { + @InterfaceType() + abstract class A { + @Field() + a!: string; + } + + @InterfaceType({ implements: A }) + abstract class B extends A { + @Field() + b!: string; + } + + @InterfaceType({ implements: B }) + abstract class C extends B { + @Field() + c!: string; + } + + @ObjectType({ implements: C }) + class D extends C { + @Field() + d!: string; + } + + @Resolver() + class TestResolver { + @Query() + testQuery(): string { + return "testQuery"; + } + } + const schemaInfo = await getSchemaInfo({ + resolvers: [TestResolver], + orphanedTypes: [A, B, C, D], + }); + schema = schemaInfo.schema; + }); + + it("should properly generate object type, implementing multi-inherited interface, with only one `implements`", async () => { + expect(printSchema(schema)).toMatchInlineSnapshot(` + "type D implements C & B & A { + a: String! + b: String! + c: String! + d: String! + } + + interface A { + a: String! + } + + interface B implements A { + a: String! + b: String! + } + + interface C implements B & A { + a: String! + b: String! + c: String! + } + + type Query { + testQuery: String! + }" + `); + }); +}); diff --git a/tests/functional/peer-dependency.ts b/tests/functional/peer-dependency.ts index 28cb71f5d..d9f8f4deb 100644 --- a/tests/functional/peer-dependency.ts +++ b/tests/functional/peer-dependency.ts @@ -1,28 +1,7 @@ -import { ensureInstalledCorrectGraphQLPackage } from "../../src/utils/graphql-version"; -import { UnmetGraphQLPeerDependencyError } from "../../src/errors"; +import { ensureInstalledCorrectGraphQLPackage } from "@/utils/graphql-version"; describe("`graphql` package peer dependency", () => { it("should have installed correct version", async () => { - ensureInstalledCorrectGraphQLPackage(); - expect(true).toBe(true); - }); - - it("should throw error when the installed version doesn't fulfill requirement", async () => { - expect.assertions(5); - jest.mock("graphql/package.json", () => ({ - version: "14.0.2", - })); - const graphqlVersion = require("../../src/utils/graphql-version"); - - try { - graphqlVersion.ensureInstalledCorrectGraphQLPackage(); - } catch (err) { - expect(err).toBeInstanceOf(Error); - expect(err).toBeInstanceOf(UnmetGraphQLPeerDependencyError); - const error = err as UnmetGraphQLPeerDependencyError; - expect(error.message).toContain("incorrect version"); - expect(error.message).toContain("graphql"); - expect(error.message).toContain("requirement"); - } + expect(ensureInstalledCorrectGraphQLPackage).not.toThrow(); }); }); diff --git a/tests/functional/query-complexity.ts b/tests/functional/query-complexity.ts new file mode 100644 index 000000000..33f97edc1 --- /dev/null +++ b/tests/functional/query-complexity.ts @@ -0,0 +1,136 @@ +import "reflect-metadata"; +import { createPubSub } from "@graphql-yoga/subscription"; +import { type GraphQLSchema, parse } from "graphql"; +import { fieldExtensionsEstimator, getComplexity, simpleEstimator } from "graphql-query-complexity"; +import { + Arg, + type ClassType, + Field, + ObjectType, + Query, + Resolver, + Subscription, + buildSchema, +} from "type-graphql"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { getSchemaInfo } from "../helpers/getSchemaInfo"; + +// Helpers +function calculateComplexityPoints(query: string, schema: GraphQLSchema) { + const complexityPoints = getComplexity({ + query: parse(query), + schema, + estimators: [fieldExtensionsEstimator(), simpleEstimator({ defaultComplexity: 1 })], + }); + + return complexityPoints; +} + +describe("Query complexity", () => { + describe("Queries", () => { + let schema: GraphQLSchema; + + beforeAll(async () => { + getMetadataStorage().clear(); + + @ObjectType() + class SampleObject { + @Field({ complexity: 10 }) + complexResolverMethod!: number; + } + + @Resolver(() => SampleObject) + class SampleResolver { + @Query() + sampleQuery(): SampleObject { + const obj = new SampleObject(); + return obj; + } + } + + schema = await buildSchema({ + resolvers: [SampleResolver], + validate: false, + }); + }); + + it("should build the schema without errors", () => { + expect(schema).toBeDefined(); + }); + + it("should properly calculate complexity points for a query with complex field resolver", () => { + const query = /* graphql */ ` + query { + sampleQuery { + complexResolverMethod + } + } + `; + const points = calculateComplexityPoints(query, schema); + + expect(points).toEqual(11); + }); + }); + + describe("Subscriptions", () => { + let schema: GraphQLSchema; + + beforeAll(async () => { + getMetadataStorage().clear(); + + @ObjectType() + class SampleObject { + @Field() + normalField!: string; + } + + function createResolver(name: string, objectType: ClassType) { + @Resolver(() => objectType) + class BaseResolver { + protected name = "baseName"; + + @Query({ name: `${name}Query` }) + baseQuery(@Arg("arg") _arg: boolean): boolean { + return true; + } + + @Subscription({ topics: "baseTopic", name: `${name}Subscription` }) + baseSubscription(@Arg("arg") _arg: boolean): boolean { + return true; + } + } + + return BaseResolver; + } + + @Resolver() + class ChildResolver extends createResolver("prefix", SampleObject) { + @Subscription({ topics: "childTopic", complexity: 4 }) + childSubscription(): boolean { + return true; + } + } + + const schemaInfo = await getSchemaInfo({ + resolvers: [ChildResolver], + pubSub: createPubSub(), + }); + + schema = schemaInfo.schema; + }); + + it("should build schema correctly", async () => { + expect(schema).toBeDefined(); + }); + + it("should properly calculate subscription complexity", () => { + const query = `subscription { + childSubscription + }`; + + const points = calculateComplexityPoints(query, schema); + + expect(points).toEqual(4); + }); + }); +}); diff --git a/tests/functional/resolvers.ts b/tests/functional/resolvers.ts index a6cd43a1f..b8cebc222 100644 --- a/tests/functional/resolvers.ts +++ b/tests/functional/resolvers.ts @@ -1,58 +1,48 @@ -// tslint:disable:member-ordering +/* eslint "@typescript-eslint/no-this-alias": ["error", { "allowedNames": ["self"] }] */ import "reflect-metadata"; +import { createPubSub } from "@graphql-yoga/subscription"; import { - IntrospectionSchema, - IntrospectionObjectType, - IntrospectionNamedTypeRef, - IntrospectionNonNullTypeRef, - IntrospectionListTypeRef, - IntrospectionField, - GraphQLSchema, - graphql, + type GraphQLSchema, + type IntrospectionField, + type IntrospectionInputObjectType, + type IntrospectionListTypeRef, + type IntrospectionNamedTypeRef, + type IntrospectionNonNullTypeRef, + type IntrospectionObjectType, + type IntrospectionSchema, TypeKind, - parse, - TypeInfo, - ValidationContext, - visit, - visitWithTypeInfo, - IntrospectionInputObjectType, - GraphQLError, + graphql, } from "graphql"; -import * as path from "path"; -import { fieldExtensionsEstimator, simpleEstimator } from "graphql-query-complexity"; -import ComplexityVisitor from "graphql-query-complexity/dist/QueryComplexity"; - import { - ObjectType, - Field, - Resolver, - Query, Arg, - InputType, - Root, - Ctx, - Mutation, Args, ArgsType, - Int, - buildSchema, + CannotDetermineGraphQLTypeError, + type ClassType, + ConflictingDefaultValuesError, + Ctx, + Field, FieldResolver, - ResolverInterface, Info, - buildSchemaSync, + InputType, + Int, + Mutation, + NoExplicitTypeError, + ObjectType, + Query, + Resolver, + type ResolverInterface, + Root, Subscription, - PubSub, - PubSubEngine, - ClassType, - ConflictingDefaultValuesError, WrongNullableListOptionError, + buildSchema, + buildSchemaSync, createParamDecorator, - CannotDetermineGraphQLTypeError, - NoExplicitTypeError, -} from "../../src"; -import { getMetadataStorage } from "../../src/metadata/getMetadataStorage"; -import { getSchemaInfo } from "../helpers/getSchemaInfo"; +} from "type-graphql"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { expectToThrow } from "../helpers/expectToThrow"; import { getInnerTypeOfNonNullableType } from "../helpers/getInnerFieldType"; +import { getSchemaInfo } from "../helpers/getSchemaInfo"; describe("Resolvers", () => { describe("Schema", () => { @@ -68,11 +58,14 @@ describe("Resolvers", () => { @InputType() class SampleInput { @Field() - field: string; + field!: string; + @Field({ defaultValue: "defaultStringFieldDefaultValue" }) - defaultStringField: string; + defaultStringField!: string; + @Field() implicitDefaultStringField: string = "implicitDefaultStringFieldDefaultValue"; + @Field() inheritDefaultField: string = "inheritDefaultFieldValue"; } @@ -80,23 +73,29 @@ describe("Resolvers", () => { @InputType() class SampleInputChild extends SampleInput { @Field({ defaultValue: "defaultValueOverwritten" }) - defaultStringField: string; + override defaultStringField!: string; + @Field() - implicitDefaultStringField: string = "implicitDefaultValueOverwritten"; + override implicitDefaultStringField: string = "implicitDefaultValueOverwritten"; } @ArgsType() class SampleArgs { @Field() - stringArg: string; - @Field(type => Int, { nullable: true }) - numberArg: number; + stringArg!: string; + + @Field(() => Int, { nullable: true }) + numberArg!: number; + @Field() - inputObjectArg: SampleInput; + inputObjectArg!: SampleInput; + @Field({ defaultValue: "defaultStringArgDefaultValue" }) - defaultStringArg: string; + defaultStringArg!: string; + @Field() implicitDefaultStringArg: string = "implicitDefaultStringArgDefaultValue"; + @Field() inheritDefaultArg: string = "inheritDefaultArgValue"; } @@ -104,20 +103,22 @@ describe("Resolvers", () => { @ArgsType() class SampleArgsChild extends SampleArgs { @Field({ defaultValue: "defaultValueOverwritten" }) - defaultStringArg: string; + override defaultStringArg!: string; + @Field() - implicitDefaultStringArg: string = "implicitDefaultValueOverwritten"; + override implicitDefaultStringArg: string = "implicitDefaultValueOverwritten"; } @ObjectType() class SampleObject { @Field() - normalField: string; + normalField!: string; @Field() - resolverFieldWithArgs: string; + resolverFieldWithArgs!: string; @Field() + // eslint-disable-next-line @typescript-eslint/class-literal-property-style get getterField(): string { return "getterField"; } @@ -127,25 +128,26 @@ describe("Resolvers", () => { return "simpleMethodField"; } - @Field(type => String) + @Field(() => String) argMethodField( - @Arg("stringArg") stringArg: string, - @Arg("booleanArg") booleanArg: boolean, - @Arg("numberArg") numberArg: number, - @Arg("inputArg") inputArg: SampleInput, - @Arg("inputChildArg") inputChildArg: SampleInputChild, - @Arg("explicitNullableArg", type => String, { nullable: true }) - explicitNullableArg: any, - @Arg("explicitArrayArg", type => [String]) explicitArrayArg: any, + @Arg("stringArg") _stringArg: string, + @Arg("booleanArg") _booleanArg: boolean, + @Arg("numberArg") _numberArg: number, + @Arg("inputArg") _inputArg: SampleInput, + @Arg("inputChildArg") _inputChildArg: SampleInputChild, + @Arg("explicitNullableArg", _type => String, { nullable: true }) + _explicitNullableArg: any, + @Arg("explicitArrayArg", () => [String]) _explicitArrayArg: any, @Arg("defaultStringArg", { defaultValue: "defaultStringArgDefaultValue" }) - defaultStringArg: string, - @Arg("nullableStringArg", { nullable: true }) nullableStringArg?: string, + _defaultStringArg: string, + @Arg("nullableStringArg", { nullable: true }) _nullableStringArg?: string, ): any { return "argMethodField"; } } @Resolver(() => SampleObject) + // eslint-disable-next-line @typescript-eslint/no-unused-vars class LambdaResolver { @Query() lambdaQuery(): boolean { @@ -154,6 +156,7 @@ describe("Resolvers", () => { } @Resolver(SampleObject) + // eslint-disable-next-line @typescript-eslint/no-unused-vars class ClassResolver { @Query() classQuery(): boolean { @@ -161,7 +164,7 @@ describe("Resolvers", () => { } } - @Resolver(of => SampleObject) + @Resolver(() => SampleObject) class SampleResolver { @Query() emptyQuery(): boolean { @@ -173,32 +176,32 @@ describe("Resolvers", () => { return "implicitStringQuery"; } - @Query(returns => String) + @Query(() => String) explicitStringQuery(): any { return "explicitStringQuery"; } - @Query(returns => String, { nullable: true }) + @Query(() => String, { nullable: true }) nullableStringQuery(): string | null { return Math.random() > 0.5 ? "explicitStringQuery" : null; } - @Query(returnType => [String]) + @Query(() => [String]) explicitStringArrayQuery(): any { return []; } - @Query(returnType => [String], { nullable: "items" }) + @Query(() => [String], { nullable: "items" }) explicitNullableItemArrayQuery(): any { return []; } - @Query(returnType => [String], { nullable: "itemsAndList" }) + @Query(() => [String], { nullable: "itemsAndList" }) explicitNullableArrayWithNullableItemsQuery(): any { return []; } - @Query(returns => String) + @Query(() => String) async promiseStringQuery(): Promise { return "promiseStringQuery"; } @@ -208,33 +211,33 @@ describe("Resolvers", () => { return {} as SampleObject; } - @Query(returns => SampleObject) + @Query(() => SampleObject) async asyncObjectQuery(): Promise { return {} as SampleObject; } @Query() - rootCtxQuery(@Root() root: any, @Ctx() ctx: any): boolean { + rootCtxQuery(@Root() _root: any, @Ctx() _ctx: any): boolean { return true; } - @Query(returns => String) - argQuery(@Arg("arg1") arg1: string, @Arg("arg2") arg2: boolean): any { + @Query(() => String) + argQuery(@Arg("arg1") _arg1: string, @Arg("arg2") _arg2: boolean): any { return "argQuery"; } - @Query(returns => String) - argsQuery(@Args() args: SampleArgs): any { + @Query(() => String) + argsQuery(@Args() _args: SampleArgs): any { return "argsQuery"; } - @Query(returns => String) - argAndArgsQuery(@Arg("arg1") arg1: string, @Args() args: SampleArgs): any { + @Query(() => String) + argAndArgsQuery(@Arg("arg1") _arg1: string, @Args() _args: SampleArgs): any { return "argAndArgsQuery"; } - @Query(returns => String) - argsInheritanceQuery(@Args() args: SampleArgsChild): any { + @Query(() => String) + argsInheritanceQuery(@Args() _args: SampleArgsChild): any { return "argsInheritanceQuery"; } @@ -244,16 +247,16 @@ describe("Resolvers", () => { } @FieldResolver() - resolverFieldWithArgs(@Arg("arg1") arg1: string, @Arg("arg2") arg2: boolean) { + resolverFieldWithArgs(@Arg("arg1") _arg1: string, @Arg("arg2") _arg2: boolean) { return "resolverFieldWithArgs"; } - @FieldResolver(type => String, { nullable: true, description: "independent" }) - independentFieldResolver(@Arg("arg1") arg1: string, @Arg("arg2") arg2: boolean) { + @FieldResolver(() => String, { nullable: true, description: "independent" }) + independentFieldResolver(@Arg("arg1") _arg1: string, @Arg("arg2") _arg2: boolean) { return "resolverFieldWithArgs"; } - @FieldResolver(type => String, { name: "overwrittenField", nullable: true }) + @FieldResolver(() => String, { name: "overwrittenField", nullable: true }) overwrittenFieldResolver() { return "overwrittenFieldResolver"; } @@ -302,7 +305,8 @@ describe("Resolvers", () => { field => field.name === "simpleMethodField", )!; const simpleMethodFieldType = simpleMethodField.type as IntrospectionNonNullTypeRef; - const simpleMethodFieldInnerType = simpleMethodFieldType.ofType as IntrospectionNamedTypeRef; + const simpleMethodFieldInnerType = + simpleMethodFieldType.ofType as IntrospectionNamedTypeRef; expect(simpleMethodField.name).toEqual("simpleMethodField"); expect(simpleMethodField.args).toHaveLength(0); @@ -372,8 +376,10 @@ describe("Resolvers", () => { const explicitArrayArg = argMethodField.args.find(arg => arg.name === "explicitArrayArg")!; const explicitArrayArgType = explicitArrayArg.type as IntrospectionNonNullTypeRef; const explicitArrayArgArrayType = explicitArrayArgType.ofType as IntrospectionListTypeRef; - const explicitArrayArgInnerType = explicitArrayArgArrayType.ofType as IntrospectionNonNullTypeRef; - const explicitArrayArgArrayItemType = explicitArrayArgInnerType.ofType as IntrospectionNamedTypeRef; + const explicitArrayArgInnerType = + explicitArrayArgArrayType.ofType as IntrospectionNonNullTypeRef; + const explicitArrayArgArrayItemType = + explicitArrayArgInnerType.ofType as IntrospectionNamedTypeRef; expect(explicitArrayArg.name).toEqual("explicitArrayArg"); expect(explicitArrayArgType.kind).toEqual(TypeKind.NON_NULL); @@ -439,7 +445,8 @@ describe("Resolvers", () => { const defaultValueStringField = sampleInputType.inputFields.find( arg => arg.name === "defaultStringField", )!; - const defaultValueStringFieldType = defaultValueStringField.type as IntrospectionNamedTypeRef; + const defaultValueStringFieldType = + defaultValueStringField.type as IntrospectionNamedTypeRef; expect(defaultValueStringField.defaultValue).toBe('"defaultStringFieldDefaultValue"'); expect(defaultValueStringFieldType).toEqual({ @@ -457,7 +464,8 @@ describe("Resolvers", () => { const implicitDefaultValueStringField = sampleInputType.inputFields.find( arg => arg.name === "implicitDefaultStringField", )!; - const implicitDefaultValueStringFieldType = implicitDefaultValueStringField.type as IntrospectionNamedTypeRef; + const implicitDefaultValueStringFieldType = + implicitDefaultValueStringField.type as IntrospectionNamedTypeRef; expect(implicitDefaultValueStringField.defaultValue).toBe( '"implicitDefaultStringFieldDefaultValue"', @@ -477,7 +485,8 @@ describe("Resolvers", () => { const defaultValueStringField = sampleInputChildType.inputFields.find( arg => arg.name === "defaultStringField", )!; - const defaultValueStringFieldType = defaultValueStringField.type as IntrospectionNamedTypeRef; + const defaultValueStringFieldType = + defaultValueStringField.type as IntrospectionNamedTypeRef; expect(defaultValueStringField.defaultValue).toBe('"defaultValueOverwritten"'); expect(defaultValueStringFieldType).toEqual({ @@ -495,7 +504,8 @@ describe("Resolvers", () => { const implicitDefaultValueStringField = sampleInputChildType.inputFields.find( arg => arg.name === "implicitDefaultStringField", )!; - const implicitDefaultValueStringFieldType = implicitDefaultValueStringField.type as IntrospectionNamedTypeRef; + const implicitDefaultValueStringFieldType = + implicitDefaultValueStringField.type as IntrospectionNamedTypeRef; expect(implicitDefaultValueStringField.defaultValue).toBe( '"implicitDefaultValueOverwritten"', @@ -583,7 +593,8 @@ describe("Resolvers", () => { const implicitDefaultStringArg = argsQuery.args.find( arg => arg.name === "implicitDefaultStringArg", )!; - const implicitDefaultStringArgType = implicitDefaultStringArg.type as IntrospectionNamedTypeRef; + const implicitDefaultStringArgType = + implicitDefaultStringArg.type as IntrospectionNamedTypeRef; expect(implicitDefaultStringArg.name).toEqual("implicitDefaultStringArg"); expect(implicitDefaultStringArg.defaultValue).toEqual('"implicitDefaultValueOverwritten"'); @@ -621,7 +632,8 @@ describe("Resolvers", () => { const implicitDefaultStringArg = argsQuery.args.find( arg => arg.name === "implicitDefaultStringArg", )!; - const implicitDefaultStringArgType = implicitDefaultStringArg.type as IntrospectionNamedTypeRef; + const implicitDefaultStringArgType = + implicitDefaultStringArg.type as IntrospectionNamedTypeRef; expect(implicitDefaultStringArg.name).toEqual("implicitDefaultStringArg"); expect(implicitDefaultStringArg.defaultValue).toEqual( @@ -691,7 +703,8 @@ describe("Resolvers", () => { const arg2Type = getInnerTypeOfNonNullableType( fieldResolverArgs.find(arg => arg.name === "arg2")!, ); - const independentFieldResolverType = independentFieldResolver.type as IntrospectionNamedTypeRef; + const independentFieldResolverType = + independentFieldResolver.type as IntrospectionNamedTypeRef; expect(independentFieldResolver.description).toEqual("independent"); expect(independentFieldResolverType.kind).toEqual("SCALAR"); @@ -734,7 +747,8 @@ describe("Resolvers", () => { it("should generate proper definition for mutation method", async () => { const emptyMutation = getMutation("emptyMutation"); const emptyMutationReturnType = emptyMutation.type as IntrospectionNonNullTypeRef; - const emptyMutationInnerReturnType = emptyMutationReturnType.ofType as IntrospectionNamedTypeRef; + const emptyMutationInnerReturnType = + emptyMutationReturnType.ofType as IntrospectionNamedTypeRef; expect(emptyMutation.args).toHaveLength(0); expect(emptyMutation.name).toEqual("emptyMutation"); @@ -746,7 +760,8 @@ describe("Resolvers", () => { it("should generate implicit string return type for query method", async () => { const implicitStringQuery = getQuery("implicitStringQuery"); const implicitStringQueryType = implicitStringQuery.type as IntrospectionNonNullTypeRef; - const implicitStringQueryInnerType = implicitStringQueryType.ofType as IntrospectionNamedTypeRef; + const implicitStringQueryInnerType = + implicitStringQueryType.ofType as IntrospectionNamedTypeRef; expect(implicitStringQueryInnerType.kind).toEqual(TypeKind.SCALAR); expect(implicitStringQueryInnerType.name).toEqual("String"); @@ -755,7 +770,8 @@ describe("Resolvers", () => { it("should generate string return type for query when explicitly set", async () => { const explicitStringQuery = getQuery("explicitStringQuery"); const explicitStringQueryType = explicitStringQuery.type as IntrospectionNonNullTypeRef; - const explicitStringQueryInnerType = explicitStringQueryType.ofType as IntrospectionNamedTypeRef; + const explicitStringQueryInnerType = + explicitStringQueryType.ofType as IntrospectionNamedTypeRef; expect(explicitStringQueryInnerType.kind).toEqual(TypeKind.SCALAR); expect(explicitStringQueryInnerType.name).toEqual("String"); @@ -797,7 +813,8 @@ describe("Resolvers", () => { const explicitNullableArrayWithNullableItemsQuery = getQuery( "explicitNullableArrayWithNullableItemsQuery", ); - const listType = explicitNullableArrayWithNullableItemsQuery.type as IntrospectionListTypeRef; + const listType = + explicitNullableArrayWithNullableItemsQuery.type as IntrospectionListTypeRef; const itemType = listType.ofType as IntrospectionNamedTypeRef; expect(listType.kind).toEqual(TypeKind.LIST); @@ -808,7 +825,8 @@ describe("Resolvers", () => { it("should generate string return type for query returning Promise", async () => { const promiseStringQuery = getQuery("promiseStringQuery"); const promiseStringQueryType = promiseStringQuery.type as IntrospectionNonNullTypeRef; - const promiseStringQueryInnerType = promiseStringQueryType.ofType as IntrospectionNamedTypeRef; + const promiseStringQueryInnerType = + promiseStringQueryType.ofType as IntrospectionNamedTypeRef; expect(promiseStringQueryInnerType.kind).toEqual(TypeKind.SCALAR); expect(promiseStringQueryInnerType.name).toEqual("String"); @@ -826,7 +844,8 @@ describe("Resolvers", () => { it("should generate object return type for query method", async () => { const implicitObjectQuery = getQuery("implicitObjectQuery"); const implicitObjectQueryType = implicitObjectQuery.type as IntrospectionNonNullTypeRef; - const implicitObjectQueryInnerType = implicitObjectQueryType.ofType as IntrospectionNamedTypeRef; + const implicitObjectQueryInnerType = + implicitObjectQueryType.ofType as IntrospectionNamedTypeRef; expect(implicitObjectQueryInnerType.kind).toEqual(TypeKind.OBJECT); expect(implicitObjectQueryInnerType.name).toEqual("SampleObject"); @@ -866,268 +885,238 @@ describe("Resolvers", () => { }); it("should throw error when arg type is not correct", async () => { - expect.assertions(3); - - try { + const error = await expectToThrow(() => { @Resolver() + // eslint-disable-next-line @typescript-eslint/no-unused-vars class SampleResolverWithError { - @Query(returns => String) - sampleQuery(@Arg("arg") arg: any): string { + @Query(() => String) + sampleQuery(@Arg("arg") _arg: any): string { return "sampleQuery"; } } - } catch (err) { - expect(err).toBeInstanceOf(Error); - expect(err).toBeInstanceOf(NoExplicitTypeError); - const error = err as NoExplicitTypeError; - expect(error.message).toMatchInlineSnapshot( - `"Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for argument named 'arg' of 'sampleQuery' of 'SampleResolverWithError' class."`, - ); - } + }); + + expect(error).toBeInstanceOf(Error); + expect(error).toBeInstanceOf(NoExplicitTypeError); + expect(error.message).toMatchInlineSnapshot( + `"Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for argument named 'arg' of 'sampleQuery' of 'SampleResolverWithError' class."`, + ); }); it("should throw error when query return type not provided", async () => { - expect.assertions(3); - - try { + const error = await expectToThrow(() => { @Resolver() + // eslint-disable-next-line @typescript-eslint/no-unused-vars class SampleResolverWithError { @Query() sampleQuery() { return "sampleQuery"; } } - } catch (err) { - expect(err).toBeInstanceOf(Error); - expect(err).toBeInstanceOf(NoExplicitTypeError); - const error = err as NoExplicitTypeError; - expect(error.message).toMatchInlineSnapshot( - `"Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for 'sampleQuery' of 'SampleResolverWithError' class."`, - ); - } + }); + + expect(error).toBeInstanceOf(Error); + expect(error).toBeInstanceOf(NoExplicitTypeError); + expect(error.message).toMatchInlineSnapshot( + `"Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for 'sampleQuery' of 'SampleResolverWithError' class."`, + ); }); it("should throw error when provided query return type is not correct", async () => { - expect.assertions(3); - - try { + const error = await expectToThrow(() => { @Resolver() + // eslint-disable-next-line @typescript-eslint/no-unused-vars class SampleResolverWithError { @Query() sampleQuery(): any { return "sampleQuery"; } } - } catch (err) { - expect(err).toBeInstanceOf(Error); - expect(err).toBeInstanceOf(NoExplicitTypeError); - const error = err as NoExplicitTypeError; - expect(error.message).toMatchInlineSnapshot( - `"Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for 'sampleQuery' of 'SampleResolverWithError' class."`, - ); - } + }); + + expect(error).toBeInstanceOf(Error); + expect(error).toBeInstanceOf(NoExplicitTypeError); + expect(error.message).toMatchInlineSnapshot( + `"Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for 'sampleQuery' of 'SampleResolverWithError' class."`, + ); }); it("should throw error when mutation return type not provided", async () => { - expect.assertions(3); - - try { + const error = await expectToThrow(() => { @Resolver() + // eslint-disable-next-line @typescript-eslint/no-unused-vars class SampleResolverWithError { @Mutation() sampleMutation() { return "sampleMutation"; } } - } catch (err) { - expect(err).toBeInstanceOf(Error); - expect(err).toBeInstanceOf(NoExplicitTypeError); - const error = err as NoExplicitTypeError; - expect(error.message).toMatchInlineSnapshot( - `"Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for 'sampleMutation' of 'SampleResolverWithError' class."`, - ); - } + }); + + expect(error).toBeInstanceOf(Error); + expect(error).toBeInstanceOf(NoExplicitTypeError); + expect(error.message).toMatchInlineSnapshot( + `"Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for 'sampleMutation' of 'SampleResolverWithError' class."`, + ); }); it("should throw error provided mutation return type is not correct", async () => { - expect.assertions(3); - - try { + const error = await expectToThrow(() => { @Resolver() + // eslint-disable-next-line @typescript-eslint/no-unused-vars class SampleResolverWithError { @Mutation() sampleMutation(): any { return "sampleMutation"; } } - } catch (err) { - expect(err).toBeInstanceOf(Error); - expect(err).toBeInstanceOf(NoExplicitTypeError); - const error = err as NoExplicitTypeError; - expect(error.message).toMatchInlineSnapshot( - `"Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for 'sampleMutation' of 'SampleResolverWithError' class."`, - ); - } + }); + + expect(error).toBeInstanceOf(Error); + expect(error).toBeInstanceOf(NoExplicitTypeError); + expect(error.message).toMatchInlineSnapshot( + `"Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for 'sampleMutation' of 'SampleResolverWithError' class."`, + ); }); it("should throw error when creating field resolver in resolver with no object type info", async () => { - expect.assertions(2); - - @ObjectType() - class SampleObjectWithError { - @Field() - sampleField: string; - } - - try { + const error = await expectToThrow(async () => { @Resolver() class SampleResolverWithError { @Query() sampleQuery(): string { return "sampleQuery"; } + @FieldResolver() sampleField() { return "sampleField"; } } + await buildSchema({ resolvers: [SampleResolverWithError], }); - } catch (err) { - expect(err).toBeInstanceOf(Error); - const error = err as NoExplicitTypeError; - expect(error.message).toMatchInlineSnapshot( - `"No provided object type in '@Resolver' decorator for class 'SampleResolverWithError!'"`, - ); - } + }); + + expect(error).toBeInstanceOf(Error); + expect(error.message).toMatchInlineSnapshot( + `"No provided object type in '@Resolver' decorator for class 'SampleResolverWithError!'"`, + ); }); it("should throw error when creating independent field resolver with no type info", async () => { - expect.assertions(3); - - @ObjectType() - class SampleObjectWithError { - @Field() - sampleField: string; - } - - try { - @Resolver(of => SampleObjectWithError) + const error = await expectToThrow(async () => { + @ObjectType() + class SampleObjectWithError { + @Field() + sampleField!: string; + } + @Resolver(() => SampleObjectWithError) class SampleResolverWithError { @Query() sampleQuery(): string { return "sampleQuery"; } + @FieldResolver() independentField() { return "independentField"; } } + await buildSchema({ resolvers: [SampleResolverWithError], }); - } catch (err) { - expect(err).toBeInstanceOf(Error); - expect(err).toBeInstanceOf(NoExplicitTypeError); - const error = err as NoExplicitTypeError; - expect(error.message).toMatchInlineSnapshot( - `"Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for 'independentField' of 'SampleResolverWithError' class."`, - ); - } + }); + + expect(error).toBeInstanceOf(Error); + expect(error).toBeInstanceOf(NoExplicitTypeError); + expect(error.message).toMatchInlineSnapshot( + `"Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for 'independentField' of 'SampleResolverWithError' class."`, + ); }); it("should throw error when using undecorated class as an explicit type", async () => { - expect.assertions(3); - - class SampleUndecoratedObject { - sampleField: string; - } - - try { + const error = await expectToThrow(async () => { + class SampleUndecoratedObject { + sampleField!: string; + } @Resolver() class SampleResolverWithError { - @Query(returns => SampleUndecoratedObject) + @Query(() => SampleUndecoratedObject) sampleQuery(): string { return "sampleQuery"; } } + await buildSchema({ resolvers: [SampleResolverWithError], }); - } catch (err) { - expect(err).toBeInstanceOf(Error); - expect(err).toBeInstanceOf(CannotDetermineGraphQLTypeError); - const error = err as CannotDetermineGraphQLTypeError; - expect(error.message).toMatchInlineSnapshot( - `"Cannot determine GraphQL output type for 'sampleQuery' of 'SampleResolverWithError' class. Is the value, that is used as its TS type or explicit type, decorated with a proper decorator or is it a proper output value?"`, - ); - } + }); + + expect(error).toBeInstanceOf(Error); + expect(error).toBeInstanceOf(CannotDetermineGraphQLTypeError); + expect(error.message).toMatchInlineSnapshot( + `"Cannot determine GraphQL output type for 'sampleQuery' of 'SampleResolverWithError' class. Is the value, that is used as its TS type or explicit type, decorated with a proper decorator or is it a proper output value?"`, + ); }); it("should throw error when using object type class is used as explicit type in place of input type", async () => { - expect.assertions(3); - - @ObjectType() - class SampleObject { - @Field() - sampleField: string; - } - - try { + const error = await expectToThrow(async () => { + @ObjectType() + class SampleObject { + @Field() + sampleField!: string; + } @Resolver() class SampleResolverWithError { @Query() - sampleQuery(@Arg("input") input: SampleObject): string { + sampleQuery(@Arg("input") _input: SampleObject): string { return "sampleQuery"; } } + await buildSchema({ resolvers: [SampleResolverWithError], }); - } catch (err) { - expect(err).toBeInstanceOf(Error); - expect(err).toBeInstanceOf(CannotDetermineGraphQLTypeError); - const error = err as CannotDetermineGraphQLTypeError; - expect(error.message).toMatchInlineSnapshot( - `"Cannot determine GraphQL input type for argument named 'input' of 'sampleQuery' of 'SampleResolverWithError' class. Is the value, that is used as its TS type or explicit type, decorated with a proper decorator or is it a proper input value?"`, - ); - } + }); + + expect(error).toBeInstanceOf(Error); + expect(error).toBeInstanceOf(CannotDetermineGraphQLTypeError); + expect(error.message).toMatchInlineSnapshot( + `"Cannot determine GraphQL input type for argument named 'input' of 'sampleQuery' of 'SampleResolverWithError' class. Is the value, that is used as its TS type or explicit type, decorated with a proper decorator or is it a proper input value?"`, + ); }); it("should throw error when using object type class is used as explicit type in place of args type", async () => { - expect.assertions(2); - - @ObjectType() - class SampleObject { - @Field() - sampleField: string; - } - - try { + const error = await expectToThrow(async () => { + @ObjectType() + class SampleObject { + @Field() + sampleField!: string; + } @Resolver() class SampleResolverWithError { @Query() - sampleQuery(@Args() args: SampleObject): string { + sampleQuery(@Args() _args: SampleObject): string { return "sampleQuery"; } } + await buildSchema({ resolvers: [SampleResolverWithError], }); - } catch (err) { - expect(err).toBeInstanceOf(Error); - const error = err as Error; - expect(error.message).toMatchInlineSnapshot( - `"The value used as a type of '@Args' for 'sampleQuery' of 'SampleResolverWithError' is not a class decorated with '@ArgsType' decorator!"`, - ); - } + }); + + expect(error).toBeInstanceOf(Error); + expect(error.message).toMatchInlineSnapshot( + `"The value used as a type of '@Args' for 'sampleQuery' of 'SampleResolverWithError' is not a class decorated with '@ArgsType' decorator!"`, + ); }); it("should throw error when declared default values are not equal", async () => { - expect.assertions(3); - - try { + const error = await expectToThrow(async () => { @InputType() class SampleInput { @Field({ defaultValue: "decoratorDefaultValue" }) @@ -1137,48 +1126,46 @@ describe("Resolvers", () => { @Resolver() class SampleResolver { @Query() - sampleQuery(@Arg("input") input: SampleInput): string { + sampleQuery(@Arg("input") _input: SampleInput): string { return "sampleQuery"; } } + await buildSchema({ resolvers: [SampleResolver] }); - } catch (err) { - expect(err).toBeInstanceOf(Error); - expect(err).toBeInstanceOf(ConflictingDefaultValuesError); - const error = err as ConflictingDefaultValuesError; - expect(error.message).toMatchInlineSnapshot( - `"The 'inputField' field of 'SampleInput' has conflicting default values. Default value from decorator ('decoratorDefaultValue') is not equal to the property initializer value ('initializerDefaultValue')."`, - ); - } + }); + + expect(error).toBeInstanceOf(Error); + expect(error).toBeInstanceOf(ConflictingDefaultValuesError); + expect(error.message).toMatchInlineSnapshot( + `"The 'inputField' field of 'SampleInput' has conflicting default values. Default value from decorator ('decoratorDefaultValue') is not equal to the property initializer value ('initializerDefaultValue')."`, + ); }); it("should throw error when list nullable option is combined with non-list type", async () => { - expect.assertions(3); - - try { + const error = await expectToThrow(async () => { @InputType() class SampleInput { @Field({ nullable: "items" }) - inputField: string; + inputField!: string; } @Resolver() class SampleResolver { @Query() - sampleQuery(@Arg("input") input: SampleInput): string { + sampleQuery(@Arg("input") _input: SampleInput): string { return "sampleQuery"; } } + const resolvers = [SampleResolver] as const; await buildSchema({ resolvers }); - } catch (err) { - expect(err).toBeInstanceOf(Error); - expect(err).toBeInstanceOf(WrongNullableListOptionError); - const error = err as WrongNullableListOptionError; - expect(error.message).toMatchInlineSnapshot( - `"Wrong nullable option set for SampleInput#inputField. You cannot combine non-list type with nullable 'items'."`, - ); - } + }); + + expect(error).toBeInstanceOf(Error); + expect(error).toBeInstanceOf(WrongNullableListOptionError); + expect(error.message).toMatchInlineSnapshot( + `"Wrong nullable option set for SampleInput#inputField. You cannot combine non-list type with nullable 'items'."`, + ); }); }); }); @@ -1194,39 +1181,18 @@ describe("Resolvers", () => { let querySecondCustom: any; let descriptorEvaluated: boolean; let sampleObjectConstructorCallCount: number; - let validationErrors: GraphQLError[]; function DescriptorDecorator(): MethodDecorator { - return (obj, methodName, descriptor: any) => { + return (_, __, descriptor: any) => { const originalMethod: Function = descriptor.value; - descriptor.value = function () { + // eslint-disable-next-line no-param-reassign + descriptor.value = (...args: unknown[]) => { descriptorEvaluated = true; - return originalMethod.apply(this, arguments); + return originalMethod.apply(null, ...args); }; }; } - // helpers - function generateAndVisitComplexMethod(maximumComplexity: number) { - const query = /* graphql */ ` - query { - sampleQuery { - complexResolverMethod - } - } - `; - const ast = parse(query); - const typeInfo = new TypeInfo(schema); - const context = new ValidationContext(schema, ast, typeInfo, err => - validationErrors.push(err), - ); - const visitor = new ComplexityVisitor(context, { - maximumComplexity, - estimators: [fieldExtensionsEstimator(), simpleEstimator({ defaultComplexity: 1 })], - }); - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - } - let mutationInputValue: any; beforeEach(() => { queryRoot = undefined; @@ -1237,7 +1203,6 @@ describe("Resolvers", () => { descriptorEvaluated = false; sampleObjectConstructorCallCount = 0; mutationInputValue = undefined; - validationErrors = []; }); beforeAll(async () => { @@ -1249,10 +1214,11 @@ describe("Resolvers", () => { @ArgsType() class SampleArgs { private readonly TRUE = true; + instanceField = Math.random(); @Field() - factor: number; + factor!: number; isTrue() { return this.TRUE; @@ -1263,7 +1229,7 @@ describe("Resolvers", () => { @ArgsType() class SampleOptionalArgs { @Field() - stringField: string; + stringField!: string; @Field({ nullable: true }) optionalField?: string; @@ -1273,10 +1239,11 @@ describe("Resolvers", () => { @InputType() class SampleInput { private readonly TRUE = true; + instanceField = Math.random(); @Field() - factor: number; + factor!: number; isTrue() { return this.TRUE; @@ -1289,15 +1256,15 @@ describe("Resolvers", () => { instanceField = Math.random(); @Field() - nestedField: SampleInput; + nestedField!: SampleInput; @Field({ nullable: true }) optionalNestedField?: SampleInput; - @Field(type => [SampleInput]) - nestedArrayField: SampleInput[]; + @Field(() => [SampleInput]) + nestedArrayField!: SampleInput[]; - @Field(type => [SampleInput], { nullable: "itemsAndList" }) + @Field(() => [SampleInput], { nullable: "itemsAndList" }) nestedOptionalArrayField?: Array; } classes.SampleNestedInput = SampleNestedInput; @@ -1306,45 +1273,53 @@ describe("Resolvers", () => { class SampleTripleNestedInput { instanceField = Math.random(); - @Field(type => [[[SampleInput]]]) - deeplyNestedInputArrayField: SampleInput[][][]; + @Field(() => [[[SampleInput]]]) + deeplyNestedInputArrayField!: SampleInput[][][]; } classes.SampleTripleNestedInput = SampleTripleNestedInput; @ArgsType() class SampleNestedArgs { @Field() - factor: number; + factor!: number; @Field() - input: SampleInput; + input!: SampleInput; } classes.SampleNestedArgs = SampleNestedArgs; @ObjectType() class SampleObject { private readonly TRUE = true; + isTrue() { return this.TRUE; } + constructor() { - sampleObjectConstructorCallCount++; + sampleObjectConstructorCallCount += 1; } instanceValue = Math.random(); @Field() - fieldResolverField: number; + fieldResolverField!: number; + @Field() - fieldResolverGetter: number; + fieldResolverGetter!: number; + @Field({ complexity: 5 }) - fieldResolverMethod: number; + fieldResolverMethod!: number; + @Field() - fieldResolverMethodWithArgs: number; + fieldResolverMethodWithArgs!: number; + @Field() - fieldResolverWithRoot: number; + fieldResolverWithRoot!: number; + @Field({ complexity: 10 }) - complexResolverMethod: number; + complexResolverMethod!: number; + @Field() get getterField(): number { return this.instanceValue; @@ -1355,7 +1330,7 @@ describe("Resolvers", () => { return this.instanceValue; } - @Field(type => String) + @Field(() => String) async asyncMethodField() { return "asyncMethodField"; } @@ -1366,13 +1341,16 @@ describe("Resolvers", () => { } } - @Resolver(of => SampleObject) + @Resolver(() => SampleObject) class SampleResolver implements ResolverInterface { factor = 1; + randomValueField = Math.random() * this.factor; + get randomValueGetter() { return Math.random() * this.factor; } + getRandomValue() { return Math.random() * this.factor; } @@ -1430,9 +1408,9 @@ describe("Resolvers", () => { mutationWithArgs(@Args() args: SampleArgs): number { if (args.isTrue()) { return args.factor * args.instanceField; - } else { - return -1.0; } + + return -1.0; } @Mutation() @@ -1445,9 +1423,9 @@ describe("Resolvers", () => { mutationWithInput(@Arg("input") input: SampleInput): number { if (input.isTrue()) { return input.factor * input.instanceField; - } else { - return -1.0; } + + return -1.0; } @Mutation() @@ -1469,14 +1447,15 @@ describe("Resolvers", () => { } @Mutation() - mutationWithInputs(@Arg("inputs", type => [SampleInput]) inputs: SampleInput[]): number { + mutationWithInputs(@Arg("inputs", () => [SampleInput]) inputs: SampleInput[]): number { + // eslint-disable-next-line prefer-destructuring mutationInputValue = inputs[0]; return inputs[0].factor; } @Mutation() mutationWithTripleArrayInputs( - @Arg("inputs", type => [[[SampleInput]]]) inputs: SampleInput[][][], + @Arg("inputs", () => [[[SampleInput]]]) inputs: SampleInput[][][], ): number { mutationInputValue = inputs; return inputs[0][0][0].factor; @@ -1509,13 +1488,13 @@ describe("Resolvers", () => { fieldResolverWithRoot(@Root() root: SampleObject) { if (root.isTrue()) { return root.instanceValue; - } else { - return -1.0; } + + return -1.0; } @FieldResolver() - fieldResolverMethodWithArgs(@Root() root: SampleObject, @Arg("arg") arg: number): number { + fieldResolverMethodWithArgs(@Root() _: SampleObject, @Arg("arg") arg: number): number { return arg; } } @@ -1537,7 +1516,7 @@ describe("Resolvers", () => { } }`; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); const getterFieldResult = result.data!.sampleQuery.getterField; expect(getterFieldResult).toBeGreaterThanOrEqual(0); @@ -1551,7 +1530,7 @@ describe("Resolvers", () => { } }`; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); const methodFieldResult = result.data!.sampleQuery.methodField; expect(methodFieldResult).toBeGreaterThanOrEqual(0); @@ -1565,7 +1544,7 @@ describe("Resolvers", () => { } }`; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); const asyncMethodFieldResult = result.data!.sampleQuery.asyncMethodField; expect(asyncMethodFieldResult).toEqual("asyncMethodField"); @@ -1578,7 +1557,7 @@ describe("Resolvers", () => { } }`; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); const methodFieldWithArgResult = result.data!.sampleQuery.methodFieldWithArg; expect(methodFieldWithArgResult).toBeGreaterThanOrEqual(0); @@ -1592,7 +1571,7 @@ describe("Resolvers", () => { } }`; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); const fieldResolverFieldResult = result.data!.sampleQuery.fieldResolverField; expect(fieldResolverFieldResult).toBeGreaterThanOrEqual(0); @@ -1606,7 +1585,7 @@ describe("Resolvers", () => { } }`; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); const fieldResolverGetterResult = result.data!.sampleQuery.fieldResolverGetter; expect(fieldResolverGetterResult).toBeGreaterThanOrEqual(0); @@ -1620,34 +1599,13 @@ describe("Resolvers", () => { } }`; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); const fieldResolverMethodResult = result.data!.sampleQuery.fieldResolverMethod; expect(fieldResolverMethodResult).toBeGreaterThanOrEqual(0); expect(fieldResolverMethodResult).toBeLessThanOrEqual(1); }); - it("should fail when a query exceeds the max allowed complexity", () => { - generateAndVisitComplexMethod(5); - expect(validationErrors.length).toEqual(1); - expect(validationErrors[0].message).toEqual( - "The query exceeds the maximum complexity of 5. Actual complexity is 11", - ); - }); - - it("should succeed when a query does not exceed the max allowed complexity", () => { - generateAndVisitComplexMethod(12); - expect(validationErrors.length).toEqual(0); - }); - - it("Complexity of a field should be overridden by complexity of a field resolver", () => { - generateAndVisitComplexMethod(9); - expect(validationErrors.length).toEqual(1); - expect(validationErrors[0].message).toEqual( - "The query exceeds the maximum complexity of 9. Actual complexity is 11", - ); - }); - it("should return value from field resolver arg", async () => { const value = 21.37; const query = `query { @@ -1656,7 +1614,7 @@ describe("Resolvers", () => { } }`; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); const resultFieldData = result.data!.sampleQuery.fieldResolverMethodWithArgs; expect(resultFieldData).toEqual(value); @@ -1669,8 +1627,8 @@ describe("Resolvers", () => { } }`; - const result1 = await graphql(schema, query); - const result2 = await graphql(schema, query); + const result1: any = await graphql({ schema, source: query }); + const result2: any = await graphql({ schema, source: query }); const getterFieldResult1 = result1.data!.sampleQuery.getterField; const getterFieldResult2 = result2.data!.sampleQuery.getterField; @@ -1687,7 +1645,7 @@ describe("Resolvers", () => { } `; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); const getterFieldValue = result.data!.sampleQuery.getterField; const methodFieldValue = result.data!.sampleQuery.getterField; @@ -1702,8 +1660,8 @@ describe("Resolvers", () => { } }`; - const result1 = await graphql(schema, query); - const result2 = await graphql(schema, query); + const result1: any = await graphql({ schema, source: query }); + const result2: any = await graphql({ schema, source: query }); const resolverFieldResult1 = result1.data!.sampleQuery.fieldResolverField; const resolverFieldResult2 = result2.data!.sampleQuery.fieldResolverField; @@ -1715,7 +1673,7 @@ describe("Resolvers", () => { mutationWithArgs(factor: 10) }`; - const mutationResult = await graphql(schema, mutation); + const mutationResult = await graphql({ schema, source: mutation }); const result = mutationResult.data!.mutationWithArgs; expect(result).toBeGreaterThanOrEqual(0); @@ -1727,7 +1685,7 @@ describe("Resolvers", () => { mutationWithOptionalArgs(stringField: "stringField") }`; - const { errors } = await graphql(schema, mutation); + const { errors } = await graphql({ schema, source: mutation }); expect(errors).toBeUndefined(); expect(mutationInputValue).toBeInstanceOf(classes.SampleOptionalArgs); @@ -1739,7 +1697,7 @@ describe("Resolvers", () => { mutationWithInput(input: { factor: 10 }) }`; - const mutationResult = await graphql(schema, mutation); + const mutationResult = await graphql({ schema, source: mutation }); const result = mutationResult.data!.mutationWithInput; expect(result).toBeGreaterThanOrEqual(0); @@ -1758,7 +1716,7 @@ describe("Resolvers", () => { }) }`; - const mutationResult = await graphql(schema, mutation); + const mutationResult = await graphql({ schema, source: mutation }); const result = mutationResult.data!.mutationWithNestedInputs; expect(result).toBeGreaterThanOrEqual(0); @@ -1783,7 +1741,7 @@ describe("Resolvers", () => { }) }`; - const mutationResult = await graphql(schema, mutation); + const mutationResult = await graphql({ schema, source: mutation }); expect(mutationResult.errors).toBeUndefined(); const mutationWithNestedInputsData = mutationResult.data!.mutationWithNestedInputs; @@ -1804,7 +1762,7 @@ describe("Resolvers", () => { mutationWithNestedArgsInput(factor: 20, input: { factor: 30 }) }`; - const mutationResult = await graphql(schema, mutation); + const mutationResult = await graphql({ schema, source: mutation }); const result = mutationResult.data!.mutationWithNestedArgsInput; expect(result).toEqual(20); @@ -1818,7 +1776,7 @@ describe("Resolvers", () => { mutationWithInputs(inputs: [{ factor: 30 }]) }`; - const mutationResult = await graphql(schema, mutation); + const mutationResult = await graphql({ schema, source: mutation }); const result = mutationResult.data!.mutationWithInputs; expect(result).toEqual(30); @@ -1832,7 +1790,7 @@ describe("Resolvers", () => { mutationWithTripleArrayInputs(inputs: [[[{ factor: 30 }]]]) }`; - const mutationResult = await graphql(schema, mutation); + const mutationResult = await graphql({ schema, source: mutation }); const result = mutationResult.data!.mutationWithTripleArrayInputs; const nestedInput = mutationInputValue[0][0][0]; @@ -1856,7 +1814,7 @@ describe("Resolvers", () => { }) }`; - const mutationResult = await graphql(schema, mutation); + const mutationResult = await graphql({ schema, source: mutation }); expect(mutationResult.errors).toBeUndefined(); const result = mutationResult.data!.mutationWithTripleNestedInputs; @@ -1880,7 +1838,7 @@ describe("Resolvers", () => { mutationWithOptionalArg }`; - const { data, errors } = await graphql(schema, mutation); + const { data, errors } = await graphql({ schema, source: mutation }); expect(errors).toBeUndefined(); expect(data!.mutationWithOptionalArg).toBeDefined(); expect(mutationInputValue).toEqual("undefined"); @@ -1894,7 +1852,7 @@ describe("Resolvers", () => { } }`; - const queryResult = await graphql(schema, query); + const queryResult: any = await graphql({ schema, source: query }); const fieldResolverWithRootValue = queryResult.data!.sampleQuery.fieldResolverWithRoot; const getterFieldValue = queryResult.data!.sampleQuery.getterField; @@ -1911,7 +1869,7 @@ describe("Resolvers", () => { } }`; - const queryResult = await graphql(schema, query); + const queryResult: any = await graphql({ schema, source: query }); const fieldResolverWithRootValue = queryResult.data!.notInstanceQuery.fieldResolverWithRoot; const getterFieldValue = queryResult.data!.notInstanceQuery.getterField; @@ -1927,7 +1885,7 @@ describe("Resolvers", () => { const root = { isRoot: true }; const context = { isContext: true }; - await graphql(schema, query, root, context); + await graphql({ schema, source: query, rootValue: root, contextValue: context }); expect(queryRoot).toEqual(root); expect(queryContext).toEqual(context); @@ -1942,7 +1900,7 @@ describe("Resolvers", () => { const root = { rootField: 2 }; const context = { contextField: "present" }; - await graphql(schema, query, root, context); + await graphql({ schema, source: query, rootValue: root, contextValue: context }); expect(queryRoot).toEqual(2); expect(queryContext).toEqual("present"); @@ -1957,7 +1915,7 @@ describe("Resolvers", () => { const root = { rootField: 2 }; const context = { contextField: "present" }; - await graphql(schema, query, root, context); + await graphql({ schema, source: query, rootValue: root, contextValue: context }); expect(queryFirstCustom.root).toEqual(root); expect(queryFirstCustom.context).toEqual(context); @@ -1972,7 +1930,7 @@ describe("Resolvers", () => { } `; - const { data } = await graphql(schema, query); + const { data } = await graphql({ schema, source: query }); expect(descriptorEvaluated).toBe(true); expect(data!.queryWithCustomDescriptorDecorator).toBe(true); @@ -1980,29 +1938,13 @@ describe("Resolvers", () => { }); describe("buildSchema", () => { - it("should load resolvers from glob paths", async () => { - getMetadataStorage().clear(); - - const { queryType } = await getSchemaInfo({ - resolvers: [path.resolve(__dirname, "../helpers/loading-from-directories/*.resolver.ts")], - }); - - const directoryQueryReturnType = getInnerTypeOfNonNullableType( - queryType.fields.find(field => field.name === "sampleQuery")!, - ); - - expect(queryType.fields).toHaveLength(1); - expect(directoryQueryReturnType.kind).toEqual(TypeKind.OBJECT); - expect(directoryQueryReturnType.name).toEqual("SampleObject"); - }); - it("should emit only things from provided `resolvers` property", async () => { getMetadataStorage().clear(); @ObjectType() class SampleObject { @Field() - sampleField: string; + sampleField!: string; } @Resolver() class SampleResolver { @@ -2014,9 +1956,10 @@ describe("Resolvers", () => { @ObjectType() class OmittedObject { @Field() - omittedField: string; + omittedField!: string; } @Resolver() + // eslint-disable-next-line @typescript-eslint/no-unused-vars class OmittedResolver { @Query() omittedQuery(): OmittedObject { @@ -2046,7 +1989,7 @@ describe("Resolvers", () => { @ObjectType() class SampleObject { @Field() - sampleFieldSync: string; + sampleFieldSync!: string; } @Resolver() class SampleResolver { @@ -2067,9 +2010,9 @@ describe("Resolvers", () => { } } `; - const { data } = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); - expect(data!.sampleQuerySync.sampleFieldSync).toEqual("sampleFieldSync"); + expect(result.data.sampleQuerySync.sampleFieldSync).toEqual("sampleFieldSync"); }); it("should generate the schema when schema is incorrect but `skipCheck` is set to true", async () => { @@ -2093,14 +2036,11 @@ describe("Resolvers", () => { it("should throw errors when no resolvers provided", async () => { getMetadataStorage().clear(); - expect.assertions(2); - try { - await buildSchema({ resolvers: [] as any }); - } catch (err) { - expect(err.message).toContain("Empty"); - expect(err.message).toContain("resolvers"); - } + const error = await expectToThrow(() => buildSchema({ resolvers: [] as any })); + + expect(error.message).toContain("Empty"); + expect(error.message).toContain("resolvers"); }); }); @@ -2111,9 +2051,10 @@ describe("Resolvers", () => { @ObjectType() class SampleObject { @Field() - sampleField: string; + sampleField!: string; + @Field() - resolvedField: string; + resolvedField!: string; } @Resolver() class SampleResolver { @@ -2122,7 +2063,8 @@ describe("Resolvers", () => { return { sampleField: "sampleField", resolvedField: "resolvedField" }; } } - @Resolver(of => SampleObject) + @Resolver(() => SampleObject) + // eslint-disable-next-line @typescript-eslint/no-unused-vars class SampleObjectResolver { @FieldResolver() resolvedField(): string { @@ -2142,7 +2084,7 @@ describe("Resolvers", () => { validate: false, }); - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); expect(result.errors).toBeUndefined(); expect(result.data!.sampleQuery).toEqual({ @@ -2157,7 +2099,7 @@ describe("Resolvers", () => { @ObjectType() class SampleObject { @Field() - sampleField: string; + sampleField!: string; } @Resolver() class SampleResolver { @@ -2166,7 +2108,8 @@ describe("Resolvers", () => { return { sampleField: "sampleField" }; } } - @Resolver(of => SampleObject) + @Resolver(() => SampleObject) + // eslint-disable-next-line @typescript-eslint/no-unused-vars class SampleObjectResolver { @FieldResolver() resolvedField(): string { @@ -2177,7 +2120,7 @@ describe("Resolvers", () => { const schemaInfo = await getSchemaInfo({ resolvers: [SampleResolver], }); - const schemaIntrospection = schemaInfo.schemaIntrospection; + const { schemaIntrospection } = schemaInfo; const sampleObjectType = schemaIntrospection.types.find( type => type.name === "SampleObject", ) as IntrospectionObjectType; @@ -2192,7 +2135,7 @@ describe("Resolvers", () => { @ObjectType() class SampleObject { @Field() - sampleField: string; + sampleField!: string; } @Resolver() class SampleResolver { @@ -2202,7 +2145,7 @@ describe("Resolvers", () => { } } function createResolver() { - @Resolver(of => SampleObject) + @Resolver(() => SampleObject) class SampleObjectResolver { @FieldResolver() resolvedField(): string { @@ -2216,7 +2159,7 @@ describe("Resolvers", () => { const schemaInfo = await getSchemaInfo({ resolvers: [SampleResolver, ChildResolver], }); - const schemaIntrospection = schemaInfo.schemaIntrospection; + const { schemaIntrospection } = schemaInfo; const sampleObjectType = schemaIntrospection.types.find( type => type.name === "SampleObject", ) as IntrospectionObjectType; @@ -2231,15 +2174,14 @@ describe("Resolvers", () => { let queryType: IntrospectionObjectType; let mutationType: IntrospectionObjectType; let subscriptionType: IntrospectionObjectType; - let thisVar: any; - let baseResolver: any; + let self: any; let childResolver: any; let overrideResolver: any; - let validationErrors: GraphQLError[]; + + const pubSub = createPubSub(); beforeEach(() => { - thisVar = null; - validationErrors = []; + self = null; }); beforeAll(async () => { @@ -2248,51 +2190,50 @@ describe("Resolvers", () => { @ObjectType() class SampleObject { @Field() - normalField: string; + normalField!: string; } @ObjectType() class DummyObject { @Field() - normalField: string; + normalField!: string; } function createResolver(name: string, objectType: ClassType) { - @Resolver(of => objectType, { isAbstract: true }) + @Resolver(() => objectType) class BaseResolver { protected name = "baseName"; @Query({ name: `${name}Query` }) - baseQuery(@Arg("arg") arg: boolean): boolean { - thisVar = this; + baseQuery(@Arg("arg") _arg: boolean): boolean { + self = this; return true; } @Mutation({ name: `${name}Mutation` }) - baseMutation(@Arg("arg") arg: boolean): boolean { - thisVar = this; + baseMutation(@Arg("arg") _arg: boolean): boolean { + self = this; return true; } @Subscription({ topics: "baseTopic", name: `${name}Subscription` }) - baseSubscription(@Arg("arg") arg: boolean): boolean { - thisVar = this; + baseSubscription(@Arg("arg") _arg: boolean): boolean { + self = this; return true; } - @Mutation(returns => Boolean, { name: `${name}Trigger` }) - async baseTrigger(@PubSub() pubSub: PubSubEngine): Promise { - await pubSub.publish("baseTopic", null); + @Mutation(() => Boolean, { name: `${name}Trigger` }) + async baseTrigger(): Promise { + pubSub.publish("baseTopic", null); return true; } @FieldResolver() resolverField(): string { - thisVar = this; + self = this; return "resolverField"; } } - baseResolver = BaseResolver; return BaseResolver; } @@ -2301,7 +2242,7 @@ describe("Resolvers", () => { class ChildResolver extends createResolver("prefix", SampleObject) { @Query() childQuery(): boolean { - thisVar = this; + self = this; return true; } @@ -2312,19 +2253,19 @@ describe("Resolvers", () => { @Mutation() childMutation(): boolean { - thisVar = this; + self = this; return true; } @Subscription({ topics: "childTopic", complexity: 4 }) childSubscription(): boolean { - thisVar = this; + self = this; return true; } - @Mutation(returns => Boolean) - async childTrigger(@PubSub() pubSub: PubSubEngine): Promise { - await pubSub.publish("childTopic", null); + @Mutation(() => Boolean) + async childTrigger(): Promise { + pubSub.publish("childTopic", null); return true; } } @@ -2333,14 +2274,14 @@ describe("Resolvers", () => { @Resolver() class OverrideResolver extends createResolver("overridden", DummyObject) { @Query() - overriddenQuery(@Arg("overriddenArg") arg: boolean): string { - thisVar = this; + overriddenQuery(@Arg("overriddenArg") _arg: boolean): string { + self = this; return "overriddenQuery"; } @Mutation({ name: "overriddenMutation" }) - overriddenMutationHandler(@Arg("overriddenArg") arg: boolean): string { - thisVar = this; + overriddenMutationHandler(@Arg("overriddenArg") _arg: boolean): string { + self = this; return "overriddenMutationHandler"; } } @@ -2348,6 +2289,7 @@ describe("Resolvers", () => { const schemaInfo = await getSchemaInfo({ resolvers: [childResolver, overrideResolver], + pubSub, }); schemaIntrospection = schemaInfo.schemaIntrospection; queryType = schemaInfo.queryType; @@ -2391,25 +2333,6 @@ describe("Resolvers", () => { expect(subscriptionNames).toContain("overriddenSubscription"); expect(prefixSubscription.args).toHaveLength(1); }); - it("should fail when a subscription exceeds the max allowed complexity", () => { - const query = `subscription { - childSubscription - }`; - const ast = parse(query); - const typeInfo = new TypeInfo(schema); - const context = new ValidationContext(schema, ast, typeInfo, err => - validationErrors.push(err), - ); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 2, - estimators: [fieldExtensionsEstimator(), simpleEstimator({ defaultComplexity: 1 })], - }); - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(validationErrors.length).toEqual(1); - expect(validationErrors[0].message).toEqual( - "The query exceeds the maximum complexity of 2. Actual complexity is 4", - ); - }); it("should generate proper object fields in schema", async () => { const sampleObjectType = schemaIntrospection.types.find( @@ -2427,7 +2350,6 @@ describe("Resolvers", () => { const overriddenQuery = queryType.fields.find(it => it.name === "overriddenQuery")!; const prefixMutation = mutationType.fields.find(it => it.name === "prefixMutation")!; const overriddenMutation = mutationType.fields.find(it => it.name === "overriddenMutation")!; - const t = getInnerTypeOfNonNullableType(prefixQuery); expect(prefixQuery.args).toHaveLength(1); expect(prefixQuery.args[0].name).toEqual("arg"); @@ -2464,10 +2386,10 @@ describe("Resolvers", () => { prefixQuery(arg: true) }`; - const { data } = await graphql(schema, query); + const { data } = await graphql({ schema, source: query }); expect(data!.prefixQuery).toEqual(true); - expect(thisVar.constructor).toEqual(childResolver); + expect(self.constructor).toEqual(childResolver); }); it("should correctly call mutation handler from base resolver class", async () => { @@ -2475,10 +2397,10 @@ describe("Resolvers", () => { prefixMutation(arg: true) }`; - const { data } = await graphql(schema, mutation); + const { data } = await graphql({ schema, source: mutation }); expect(data!.prefixMutation).toEqual(true); - expect(thisVar.constructor).toEqual(childResolver); + expect(self.constructor).toEqual(childResolver); }); it("should correctly call query handler from child resolver class", async () => { @@ -2486,10 +2408,10 @@ describe("Resolvers", () => { childQuery }`; - const { data } = await graphql(schema, query); + const { data } = await graphql({ schema, source: query }); expect(data!.childQuery).toEqual(true); - expect(thisVar.constructor).toEqual(childResolver); + expect(self.constructor).toEqual(childResolver); }); it("should correctly call mutation handler from child resolver class", async () => { @@ -2497,10 +2419,10 @@ describe("Resolvers", () => { childMutation }`; - const { data } = await graphql(schema, mutation); + const { data } = await graphql({ schema, source: mutation }); expect(data!.childMutation).toEqual(true); - expect(thisVar.constructor).toEqual(childResolver); + expect(self.constructor).toEqual(childResolver); }); it("should correctly call field resolver handler from base resolver class", async () => { @@ -2510,10 +2432,10 @@ describe("Resolvers", () => { } }`; - const { data } = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); - expect(data!.objectQuery.resolverField).toEqual("resolverField"); - expect(thisVar.constructor).toEqual(childResolver); + expect(result.data!.objectQuery.resolverField).toEqual("resolverField"); + expect(self.constructor).toEqual(childResolver); }); it("should correctly call overridden query handler from child resolver class", async () => { @@ -2521,10 +2443,10 @@ describe("Resolvers", () => { overriddenQuery(overriddenArg: true) }`; - const { data } = await graphql(schema, query); + const { data } = await graphql({ schema, source: query }); expect(data!.overriddenQuery).toEqual("overriddenQuery"); - expect(thisVar.constructor).toEqual(overrideResolver); + expect(self.constructor).toEqual(overrideResolver); }); it("should correctly call overridden mutation handler from child resolver class", async () => { @@ -2532,10 +2454,10 @@ describe("Resolvers", () => { overriddenMutation(overriddenArg: true) }`; - const { data } = await graphql(schema, mutation); + const { data } = await graphql({ schema, source: mutation }); expect(data!.overriddenMutation).toEqual("overriddenMutationHandler"); - expect(thisVar.constructor).toEqual(overrideResolver); + expect(self.constructor).toEqual(overrideResolver); }); it("should have access to inherited properties from base resolver class", async () => { @@ -2543,9 +2465,9 @@ describe("Resolvers", () => { childQuery }`; - await graphql(schema, query); + await graphql({ schema, source: query }); - expect(thisVar.name).toEqual("baseName"); + expect(self.name).toEqual("baseName"); }); it("should get child class instance when calling base resolver handler", async () => { @@ -2553,9 +2475,74 @@ describe("Resolvers", () => { prefixQuery(arg: true) }`; - await graphql(schema, query); + await graphql({ schema, source: query }); + + expect(self).toBeInstanceOf(childResolver); + }); + + it("should allow duplicate fieldResolver methods with different schema names for inherited resolvers", async () => { + getMetadataStorage().clear(); + const INHERITED_DYNAMIC_FIELD_NAME_1 = "dynamicallyNamedMethod1"; + const INHERITED_DYNAMIC_FIELD_NAME_2 = "dynamicallyNamedMethod2"; + + const withDynamicallyNamedFieldResolver = ( + classType: ClassType, + BaseResolverClass: ClassType, + name: string, + ) => { + @Resolver(() => classType) + class DynamicallyNamedFieldResolver extends BaseResolverClass { + @FieldResolver({ name }) + dynamicallyNamedField(): boolean { + return true; + } + } + return DynamicallyNamedFieldResolver; + }; + + @ObjectType() + class SampleObject { + @Field() + sampleField!: string; + } + + @Resolver() + class SampleResolver { + @Query(() => SampleObject) + sampleObject(): SampleObject { + return { sampleField: "sampleText" }; + } + } + + const DynamicallyNamedFieldResolver1 = withDynamicallyNamedFieldResolver( + SampleObject, + SampleResolver, + INHERITED_DYNAMIC_FIELD_NAME_1, + ); + const DynamicallyNamedFieldResolver2 = withDynamicallyNamedFieldResolver( + SampleObject, + DynamicallyNamedFieldResolver1, + INHERITED_DYNAMIC_FIELD_NAME_2, + ); + + const schemaInfo = await getSchemaInfo({ + resolvers: [DynamicallyNamedFieldResolver2], + }); + schemaIntrospection = schemaInfo.schemaIntrospection; + const sampleObjectType = schemaIntrospection.types.find( + type => type.name === "SampleObject", + ) as IntrospectionObjectType; + + const dynamicField1 = sampleObjectType.fields.find( + field => field.name === INHERITED_DYNAMIC_FIELD_NAME_1, + )!; + + const dynamicField2 = sampleObjectType.fields.find( + field => field.name === INHERITED_DYNAMIC_FIELD_NAME_2, + )!; - expect(thisVar).toBeInstanceOf(childResolver); + expect(dynamicField1).toBeDefined(); + expect(dynamicField2).toBeDefined(); }); }); }); diff --git a/tests/functional/scalars.ts b/tests/functional/scalars.ts index 90703d809..7a19bf7b1 100644 --- a/tests/functional/scalars.ts +++ b/tests/functional/scalars.ts @@ -1,43 +1,38 @@ import "reflect-metadata"; import { - graphql, - IntrospectionSchema, - IntrospectionObjectType, - IntrospectionNamedTypeRef, - IntrospectionNonNullTypeRef, - GraphQLSchema, + type GraphQLSchema, + type IntrospectionNamedTypeRef, + type IntrospectionNonNullTypeRef, + type IntrospectionObjectType, + type IntrospectionSchema, TypeKind, + graphql, } from "graphql"; - import { - ObjectType, - InputType, - Resolver, - Field, - Query, Arg, - buildSchema, - ID, + Field, Float, - Int, GraphQLISODateTime, GraphQLTimestamp, -} from "../../src"; -import { getSchemaInfo } from "../helpers/getSchemaInfo"; + ID, + Int, + ObjectType, + Query, + Resolver, +} from "type-graphql"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; import { CustomScalar, CustomType, ObjectScalar } from "../helpers/customScalar"; import { getSampleObjectFieldType } from "../helpers/getSampleObjectFieldType"; -import { getMetadataStorage } from "../../src/metadata/getMetadataStorage"; +import { getSchemaInfo } from "../helpers/getSchemaInfo"; describe("Scalars", () => { let schemaIntrospection: IntrospectionSchema; let sampleObject: IntrospectionObjectType; let schema: GraphQLSchema; - let argScalar: string | undefined; - let argDate: Date | undefined; + beforeEach(() => { argScalar = undefined; - argDate = undefined; }); beforeAll(async () => { @@ -45,78 +40,77 @@ describe("Scalars", () => { @ObjectType() class SampleObject { - @Field(type => ID) + @Field(() => ID) idField: any; @Field() - implicitFloatField: number; + implicitFloatField!: number; - @Field(type => Float) + @Field(() => Float) explicitFloatField: any; - @Field(type => Int) + @Field(() => Int) intField: any; @Field() - implicitStringField: string; + implicitStringField!: string; - @Field(type => String) + @Field(() => String) explicitStringField: any; @Field() - implicitBooleanField: boolean; + implicitBooleanField!: boolean; - @Field(type => Boolean) + @Field(() => Boolean) explicitBooleanField: any; @Field() - implicitDateField: Date; + implicitDateField!: Date; - @Field(type => Date) + @Field(() => Date) explicitDateField: any; - @Field(type => GraphQLISODateTime) + @Field(() => GraphQLISODateTime) ISODateField: any; - @Field(type => GraphQLTimestamp) + @Field(() => GraphQLTimestamp) timestampField: any; - @Field(type => CustomScalar) + @Field(() => CustomScalar) customScalarField: any; } - @Resolver(of => SampleObject) + @Resolver(() => SampleObject) class SampleResolver { @Query() mainQuery(): SampleObject { return {} as any; } - @Query(returns => CustomScalar) + @Query(() => CustomScalar) returnScalar(): string { return "returnScalar"; } - @Query(returns => Boolean) - argScalar(@Arg("scalar", type => CustomScalar) scalar: any): any { + @Query(() => Boolean) + argScalar(@Arg("scalar", () => CustomScalar) scalar: any): any { argScalar = scalar; return true; } - @Query(returns => Boolean) - objectArgScalar(@Arg("scalar", type => ObjectScalar) scalar: any): any { + @Query(() => Boolean) + objectArgScalar(@Arg("scalar", () => ObjectScalar) scalar: any): any { argScalar = scalar; return true; } - @Query(returns => Date) + @Query(() => Date) returnDate(): any { return new Date(); } @Query() - argDate(@Arg("date", type => Date) date: any): boolean { - argDate = date; + argDate(@Arg("date", () => Date) _date: any): boolean { return true; } } @@ -187,21 +181,21 @@ describe("Scalars", () => { const explicitDateFieldType = getFieldType("explicitDateField"); expect(explicitDateFieldType.kind).toEqual(TypeKind.SCALAR); - expect(explicitDateFieldType.name).toEqual("DateTime"); + expect(explicitDateFieldType.name).toEqual("DateTimeISO"); }); it("should generate Date scalar field type when prop type is Date", async () => { const implicitStringFieldType = getFieldType("implicitDateField"); expect(implicitStringFieldType.kind).toEqual(TypeKind.SCALAR); - expect(implicitStringFieldType.name).toEqual("DateTime"); + expect(implicitStringFieldType.name).toEqual("DateTimeISO"); }); it("should generate ISODate scalar field type", async () => { const ISODateFieldType = getFieldType("ISODateField"); expect(ISODateFieldType.kind).toEqual(TypeKind.SCALAR); - expect(ISODateFieldType.name).toEqual("DateTime"); + expect(ISODateFieldType.name).toEqual("DateTimeISO"); }); it("should generate Timestamp scalar field type", async () => { @@ -224,8 +218,8 @@ describe("Scalars", () => { const query = `query { returnScalar }`; - const result = await graphql(schema, query); - const returnScalar = result.data!.returnScalar; + const result: any = await graphql({ schema, source: query }); + const { returnScalar } = result.data!; expect(returnScalar).toEqual("TypeGraphQL serialize"); }); @@ -234,7 +228,7 @@ describe("Scalars", () => { const query = `query { argScalar(scalar: "test") }`; - await graphql(schema, query); + await graphql({ schema, source: query }); expect(argScalar!).toEqual("TypeGraphQL parseLiteral"); }); @@ -243,411 +237,12 @@ describe("Scalars", () => { const query = `query { objectArgScalar(scalar: "test") }`; - await graphql(schema, query); + await graphql({ schema, source: query }); expect(argScalar!).toEqual({ value: "TypeGraphQL parseLiteral" }); }); }); - describe("Bulit-in scalars", () => { - let sampleResolver: any; - let localArgDate: Date | undefined; - - beforeAll(async () => { - getMetadataStorage().clear(); - - @InputType() - class DateInput { - @Field(type => Date) - date: any; - - @Field(type => Date, { nullable: true }) - nullableDate?: any; - } - - @Resolver() - class SampleResolver { - @Query(returns => Date) - returnDate(): any { - return new Date(); - } - - @Query(returns => Date, { nullable: true }) - nullableReturnDate(): Date | null { - return null; - } - - @Query(returns => Date) - returnStringAsDate(): any { - return new Date().toISOString(); - } - - @Query() - argDate(@Arg("date", type => Date) date: any): boolean { - localArgDate = date; - return true; - } - - @Query() - nullableArgDate( - @Arg("date", type => Date, { nullable: true }) - date: any, - ): boolean { - localArgDate = date; - return true; - } - - @Query() - inputDate(@Arg("input", type => DateInput) dateInput: any): boolean { - localArgDate = dateInput.date; - return true; - } - } - - sampleResolver = SampleResolver; - }); - - beforeEach(() => { - argDate = undefined; - }); - - describe("GraphQLISODate", () => { - let localSchema: GraphQLSchema; - - beforeAll(async () => { - localSchema = await buildSchema({ - resolvers: [sampleResolver], - dateScalarMode: "isoDate", - validate: false, - }); - }); - - it("should properly serialize date", async () => { - const query = `query { - returnDate - }`; - const beforeQuery = Date.now(); - const result = await graphql(localSchema, query); - const afterQuery = Date.now(); - const returnDate = Date.parse(result.data!.returnDate); - - expect(returnDate).toBeLessThanOrEqual(afterQuery); - expect(returnDate).toBeGreaterThanOrEqual(beforeQuery); - }); - - it("should not fail while serializing null", async () => { - const query = `query { - nullableReturnDate - }`; - - const result = await graphql(localSchema, query); - - expect(result.errors).toBeUndefined(); - expect(result.data!.nullableReturnDate).toBeNull(); - }); - - it("should throw error when unable to serialize value as date", async () => { - const query = `query { - returnStringAsDate - }`; - - const { errors } = await graphql(localSchema, query); - - expect(errors).toHaveLength(1); - expect(errors![0].message).toContain(`Unable to serialize value`); - expect(errors![0].message).toContain(`it's not an instance of 'Date'`); - }); - - it("should properly parse date from arg", async () => { - const now = new Date(); - const query = `query { - argDate(date: "${now.toISOString()}") - }`; - await graphql(localSchema, query); - - expect(now.getTime()).toEqual(localArgDate!.getTime()); - }); - - it("should fail while providing wrong value type as date arg", async () => { - const query = `query { - argDate(date: true) - }`; - - const { errors } = await graphql(localSchema, query); - - expect(errors).toHaveLength(1); - expect(errors![0].message).toMatchInlineSnapshot( - `"Expected value of type \\"DateTime!\\", found true; Unable to parse literal value of kind 'BooleanValue' as GraphQLISODateTime scalar supports only 'StringValue' ones"`, - ); - }); - - it("should not fail while parsing null date arg", async () => { - const query = `query { - nullableArgDate(date: null) - }`; - - await graphql(localSchema, query); - - expect(localArgDate).toBeNull(); - }); - - it("should properly parse date from input", async () => { - const now = new Date(); - const query = `query { - inputDate(input: { date: "${now.toISOString()}" }) - }`; - await graphql(localSchema, query); - - expect(now.getTime()).toEqual(localArgDate!.getTime()); - }); - - it("should fail while providing wrong value type as date input", async () => { - const query = `query { - inputDate(input: { date: true }) - }`; - - const { errors } = await graphql(localSchema, query); - - expect(errors).toHaveLength(1); - expect(errors![0].message).toMatchInlineSnapshot( - `"Expected value of type \\"DateTime!\\", found true; Unable to parse literal value of kind 'BooleanValue' as GraphQLISODateTime scalar supports only 'StringValue' ones"`, - ); - }); - - it("should not fail while parsing null from date input", async () => { - const now = new Date(); - const query = `query { - inputDate(input: { date: "${now.toISOString()}", nullableDate: null }) - }`; - - const result = await graphql(localSchema, query); - - expect(result.errors).toBeUndefined(); - }); - - it("should properly parse date from variable", async () => { - const now = new Date(); - const query = `query DateQuery($date: DateTime!) { - inputDate(input: {date: $date}) - }`; - await graphql({ - schema: localSchema, - source: query, - variableValues: { - date: now.toISOString(), - }, - }); - - expect(now.getTime()).toEqual(localArgDate!.getTime()); - }); - - it("should fail while providing wrong value type for as date variable", async () => { - const query = `query DateQuery($date: DateTime!) { - inputDate(input: {date: $date}) - }`; - - const { errors } = await graphql({ - schema: localSchema, - source: query, - variableValues: { - date: true, - }, - }); - - expect(errors).toHaveLength(1); - expect(errors![0].message).toMatchInlineSnapshot( - `"Variable \\"$date\\" got invalid value true; Expected type \\"DateTime\\". Unable to parse value 'true' as GraphQLISODateTime scalar supports only string values"`, - ); - }); - - it("should not fail while parsing null from date variable", async () => { - const now = new Date(); - const query = `query DateQuery($date: DateTime!, $nullableDate: DateTime) { - inputDate(input: {date: $date, nullableDate: $nullableDate}) - }`; - - const result = await graphql({ - schema: localSchema, - source: query, - variableValues: { - date: now.toISOString(), - nullableDate: null, - }, - }); - - expect(result.errors).toBeUndefined(); - }); - }); - - describe("GraphQLTimestamp", () => { - let localSchema: GraphQLSchema; - - beforeAll(async () => { - localSchema = await buildSchema({ - resolvers: [sampleResolver], - dateScalarMode: "timestamp", - validate: false, - }); - }); - - it("should properly serialize date", async () => { - const query = `query { - returnDate - }`; - const beforeQuery = Date.now(); - const result = await graphql(localSchema, query); - const afterQuery = Date.now(); - const returnDate = result.data!.returnDate; - - expect(returnDate).toBeLessThanOrEqual(afterQuery); - expect(returnDate).toBeGreaterThanOrEqual(beforeQuery); - }); - - it("should not fail while serializing null", async () => { - const query = `query { - nullableReturnDate - }`; - - const result = await graphql(localSchema, query); - - expect(result.errors).toBeUndefined(); - expect(result.data!.nullableReturnDate).toBeNull(); - }); - - it("should throw error when unable to serialize value as date", async () => { - const query = `query { - returnStringAsDate - }`; - - const { errors } = await graphql(localSchema, query); - - expect(errors).toHaveLength(1); - expect(errors![0].message).toContain(`Unable to serialize value`); - expect(errors![0].message).toContain(`it's not an instance of 'Date'`); - }); - - it("should properly parse date from arg", async () => { - const now = new Date(); - const query = `query { - argDate(date: ${now.getTime()}) - }`; - await graphql(localSchema, query); - - expect(now.getTime()).toEqual(localArgDate!.getTime()); - }); - - it("should fail while providing wrong value type as date arg", async () => { - const query = `query { - argDate(date: true) - }`; - - const { errors } = await graphql(localSchema, query); - - expect(errors).toHaveLength(1); - expect(errors![0].message).toMatchInlineSnapshot( - `"Expected value of type \\"Timestamp!\\", found true; Unable to parse literal value of kind 'BooleanValue' as GraphQLTimestamp scalar supports only 'IntValue' ones"`, - ); - }); - - it("should not fail while parsing null date arg", async () => { - const query = `query { - nullableArgDate(date: null) - }`; - - await graphql(localSchema, query); - - expect(localArgDate).toBeNull(); - }); - - it("should properly parse date from input", async () => { - const now = new Date(); - const query = `query { - inputDate(input: {date: ${now.getTime()}}) - }`; - await graphql(localSchema, query); - - expect(now.getTime()).toEqual(localArgDate!.getTime()); - }); - - it("should fail while providing wrong value type as date input", async () => { - const query = `query { - inputDate(input: { date: true }) - }`; - - const { errors } = await graphql(localSchema, query); - - expect(errors).toHaveLength(1); - expect(errors![0].message).toMatchInlineSnapshot( - `"Expected value of type \\"Timestamp!\\", found true; Unable to parse literal value of kind 'BooleanValue' as GraphQLTimestamp scalar supports only 'IntValue' ones"`, - ); - }); - - it("should not fail while parsing null from date input", async () => { - const now = new Date(); - const query = `query { - inputDate(input: { date: ${now.getTime()}, nullableDate: null }) - }`; - - const result = await graphql(localSchema, query); - - expect(result.errors).toBeUndefined(); - }); - - it("should properly parse date from variable", async () => { - const now = new Date(); - const query = `query DateQuery($date: Timestamp!) { - inputDate(input: {date: $date}) - }`; - await graphql({ - schema: localSchema, - source: query, - variableValues: { - date: now.getTime(), - }, - }); - - expect(now.getTime()).toEqual(localArgDate!.getTime()); - }); - - it("should fail while providing wrong value type for as date variable", async () => { - const query = `query DateQuery($date: Timestamp!) { - inputDate(input: {date: $date}) - }`; - - const { errors } = await graphql({ - schema: localSchema, - source: query, - variableValues: { - date: true, - }, - }); - - expect(errors).toHaveLength(1); - expect(errors![0].message).toMatchInlineSnapshot( - `"Variable \\"$date\\" got invalid value true; Expected type \\"Timestamp\\". Unable to parse value 'true' as GraphQLTimestamp scalar supports only number values"`, - ); - }); - - it("should not fail while parsing null from date variable", async () => { - const now = new Date(); - const query = `query DateQuery($date: Timestamp!, $nullableDate: Timestamp) { - inputDate(input: {date: $date, nullableDate: $nullableDate}) - }`; - - const result = await graphql({ - schema: localSchema, - source: query, - variableValues: { - date: now.getTime(), - nullableDate: null, - }, - }); - - expect(result.errors).toBeUndefined(); - }); - }); - }); - describe("Settings", () => { let sampleResolver: any; @@ -656,11 +251,11 @@ describe("Scalars", () => { @ObjectType() class SampleObject { - @Field(type => Date) + @Field(() => Date) dateField: any; } - @Resolver(of => SampleObject) + @Resolver(() => SampleObject) class SampleResolver { @Query() mainQuery(): SampleObject { @@ -677,24 +272,24 @@ describe("Scalars", () => { const dateFieldType = getSampleObjectFieldType(schemaInfo.schemaIntrospection)("dateField"); expect(dateFieldType.kind).toEqual(TypeKind.SCALAR); - expect(dateFieldType.name).toEqual("DateTime"); + expect(dateFieldType.name).toEqual("DateTimeISO"); }); - it("should generate date scalar field type when dateScalarMode is isoDate", async () => { + it("should generate DateTime scalar field type when scalarsMap is using GraphQLISODateTime", async () => { const schemaInfo = await getSchemaInfo({ resolvers: [sampleResolver], - dateScalarMode: "isoDate", + scalarsMap: [{ type: Date, scalar: GraphQLISODateTime }], }); const dateFieldType = getSampleObjectFieldType(schemaInfo.schemaIntrospection)("dateField"); expect(dateFieldType.kind).toEqual(TypeKind.SCALAR); - expect(dateFieldType.name).toEqual("DateTime"); + expect(dateFieldType.name).toEqual("DateTimeISO"); }); - it("should generate timestamp scalar field type when dateScalarMode is timestamp", async () => { + it("should generate Timestamp scalar field type when scalarsMap is using GraphQLTimestamp", async () => { const schemaInfo = await getSchemaInfo({ resolvers: [sampleResolver], - dateScalarMode: "timestamp", + scalarsMap: [{ type: Date, scalar: GraphQLTimestamp }], }); const dateFieldType = getSampleObjectFieldType(schemaInfo.schemaIntrospection)("dateField"); @@ -708,10 +303,10 @@ describe("Scalars", () => { @ObjectType() class SampleObject { @Field() - customField: CustomType; + customField!: CustomType; } - @Resolver(of => SampleObject) + @Resolver(() => SampleObject) class SampleResolver { @Query() mainQuery(): SampleObject { @@ -734,11 +329,11 @@ describe("Scalars", () => { @ObjectType() class SampleObject { - @Field(type => Date) + @Field(() => Date) dateField: any; } - @Resolver(of => SampleObject) + @Resolver(() => SampleObject) class SampleResolver { @Query() mainQuery(): SampleObject { diff --git a/tests/functional/simple-resolvers.ts b/tests/functional/simple-resolvers.ts index 3b1497f43..e27af3ece 100644 --- a/tests/functional/simple-resolvers.ts +++ b/tests/functional/simple-resolvers.ts @@ -1,9 +1,8 @@ import "reflect-metadata"; +import { type GraphQLSchema, execute } from "graphql"; import gql from "graphql-tag"; -import { GraphQLSchema, execute } from "graphql"; -import { MiddlewareFn, ObjectType, Field, buildSchema, Resolver, Query } from "../../src"; - -import { getMetadataStorage } from "../../src/metadata/getMetadataStorage"; +import { Field, type MiddlewareFn, ObjectType, Query, Resolver, buildSchema } from "type-graphql"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; describe("Simple resolvers", () => { let schema: GraphQLSchema; @@ -12,30 +11,30 @@ describe("Simple resolvers", () => { beforeAll(async () => { getMetadataStorage().clear(); - const testMiddleware: MiddlewareFn = async ({}, next) => { - middlewareLogs.push("middleware extecuted"); + const testMiddleware: MiddlewareFn = async (_, next) => { + middlewareLogs.push("middleware executed"); return next(); }; @ObjectType() class NormalObject { @Field() - normalField: string; + normalField!: string; } @ObjectType() class ObjectWithSimpleField { @Field({ simple: true }) - simpleField: string; + simpleField!: string; } @ObjectType({ simpleResolvers: true }) class SimpleObject { @Field() - simpleField: string; + simpleField!: string; } @ObjectType({ simpleResolvers: true }) class SimpleObjectWithNormalField { @Field({ simple: false }) - normalField: string; + normalField!: string; } @Resolver() diff --git a/tests/functional/subscriptions.ts b/tests/functional/subscriptions.ts index 723575dc3..82ba5d8fe 100644 --- a/tests/functional/subscriptions.ts +++ b/tests/functional/subscriptions.ts @@ -1,46 +1,42 @@ import "reflect-metadata"; +import { createPubSub } from "@graphql-yoga/subscription"; import { - GraphQLSchema, - IntrospectionObjectType, - IntrospectionSchema, + type DocumentNode, + type ExecutionResult, + type GraphQLSchema, + type IntrospectionObjectType, TypeKind, - graphql, - subscribe, - ExecutionResult, execute, - DocumentNode, + subscribe, } from "graphql"; import gql from "graphql-tag"; -import { EventEmitter } from "events"; -import { PubSub as LocalPubSub } from "graphql-subscriptions"; - import { - Subscription, - Resolver, - Query, Arg, - ObjectType, + Authorized, Field, - PubSub, + Float, + Int, + MissingPubSubError, + MissingSubscriptionTopicsError, Mutation, + ObjectType, + Query, + Resolver, Root, - Publisher, - PubSubEngine, - Float, + Subscription, buildSchema, - MissingSubscriptionTopicsError, - Authorized, - Int, -} from "../../src"; -import { getMetadataStorage } from "../../src/metadata/getMetadataStorage"; -import { getSchemaInfo } from "../helpers/getSchemaInfo"; +} from "type-graphql"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { expectToThrow } from "../helpers/expectToThrow"; import { getInnerTypeOfNonNullableType, getItemTypeOfList } from "../helpers/getInnerFieldType"; -import sleep from "../helpers/sleep"; +import { getSchemaInfo } from "../helpers/getSchemaInfo"; +import { sleep } from "../helpers/sleep"; describe("Subscriptions", () => { + const pubSub = createPubSub(); + describe("Schema", () => { let schema: GraphQLSchema; - let schemaIntrospection: IntrospectionSchema; let subscriptionType: IntrospectionObjectType; beforeAll(async () => { @@ -49,7 +45,7 @@ describe("Subscriptions", () => { @ObjectType() class SampleObject { @Field() - sampleField: string; + sampleField!: string; } @Resolver() @@ -58,6 +54,7 @@ describe("Subscriptions", () => { sampleQuery(): boolean { return true; } + @Subscription({ topics: "STH" }) sampleSubscription(): boolean { return true; @@ -65,22 +62,22 @@ describe("Subscriptions", () => { @Subscription({ topics: "STH" }) subscriptionWithArgs( - @Arg("stringArg") stringArg: string, - @Arg("booleanArg") booleanArg: boolean, + @Arg("stringArg") _stringArg: string, + @Arg("booleanArg") _booleanArg: boolean, ): boolean { return true; } - @Subscription(returns => [SampleObject], { topics: "STH" }) + @Subscription(() => [SampleObject], { topics: "STH" }) subscriptionWithExplicitType(): any { return true; } } const schemaInfo = await getSchemaInfo({ resolvers: [SampleResolver], + pubSub, }); schema = schemaInfo.schema; - schemaIntrospection = schemaInfo.schemaIntrospection; subscriptionType = schemaInfo.subscriptionType!; }); @@ -129,15 +126,14 @@ describe("Subscriptions", () => { describe("Functional", () => { let schema: GraphQLSchema; - const localPubSub: PubSubEngine = new LocalPubSub(); beforeAll(async () => { getMetadataStorage().clear(); @ObjectType() class SampleObject { - @Field(type => Float) - value: number; + @Field(() => Float) + value!: number; } const SAMPLE_TOPIC = "SAMPLE"; @@ -150,50 +146,36 @@ describe("Subscriptions", () => { return true; } - @Mutation(returns => Boolean) - async pubSubMutation( - @Arg("value") value: number, - @PubSub() pubSub: PubSubEngine, - ): Promise { - await pubSub.publish(SAMPLE_TOPIC, value); + @Mutation(() => Boolean) + async pubSubMutation(@Arg("value") value: number): Promise { + pubSub.publish(SAMPLE_TOPIC, value); return true; } - @Mutation(returns => Boolean) + @Mutation(() => Boolean) async pubSubMutationCustomSubscription(@Arg("value") value: number): Promise { - await localPubSub.publish(CUSTOM_SUBSCRIBE_TOPIC, value); + pubSub.publish(CUSTOM_SUBSCRIBE_TOPIC, value); return true; } - @Mutation(returns => Boolean) + @Mutation(() => Boolean) async pubSubMutationDynamicTopic( @Arg("value") value: number, @Arg("topic") topic: string, - @PubSub() pubSub: PubSubEngine, ): Promise { - await pubSub.publish(topic, value); + pubSub.publish(topic, value); return true; } - @Mutation(returns => Boolean) - async pubSubPublisherMutation( - @Arg("value") value: number, - @PubSub(SAMPLE_TOPIC) publish: Publisher, - ): Promise { - await publish(value); + @Mutation(() => Boolean) + async pubSubOtherMutation(@Arg("value") value: number): Promise { + pubSub.publish(OTHER_TOPIC, value); return true; } - @Mutation(returns => Boolean) - async pubSubOtherMutation( - @Arg("value") value: number, - @PubSub() pubSub: PubSubEngine, - ): Promise { - await pubSub.publish(OTHER_TOPIC, value); - return true; - } - - @Subscription({ topics: SAMPLE_TOPIC }) + @Subscription({ + topics: SAMPLE_TOPIC, + }) sampleTopicSubscription(@Root() value: number): SampleObject { return { value }; } @@ -206,17 +188,26 @@ describe("Subscriptions", () => { return { value }; } - @Subscription({ topics: [SAMPLE_TOPIC, OTHER_TOPIC] }) + @Subscription({ + topics: [SAMPLE_TOPIC, OTHER_TOPIC], + }) multipleTopicSubscription(@Root() value: number): SampleObject { return { value }; } - @Subscription({ topics: ({ args }) => args.topic }) - dynamicTopicSubscription(@Root() value: number, @Arg("topic") topic: string): SampleObject { + @Subscription({ + topics: ({ args }) => args.topic, + }) + dynamicTopicSubscription( + @Root() value: number, + @Arg("topic") _topic: string, + ): SampleObject { return { value }; } - @Subscription({ subscribe: () => localPubSub.asyncIterator(CUSTOM_SUBSCRIBE_TOPIC) }) + @Subscription({ + subscribe: () => pubSub.subscribe(CUSTOM_SUBSCRIBE_TOPIC), + }) customSubscribeSubscription(@Root() value: number): SampleObject { return { value }; } @@ -224,6 +215,7 @@ describe("Subscriptions", () => { schema = await buildSchema({ resolvers: [SampleResolver], + pubSub, }); }); @@ -238,17 +230,19 @@ describe("Subscriptions", () => { subscriptionVariables?: object; onSubscribedData: (data: any) => void; }) { - const results = (await subscribe( + const results = (await subscribe({ schema, - options.subscription, - null, - null, - options.subscriptionVariables, - )) as AsyncIterableIterator; + document: options.subscription, + variableValues: options.subscriptionVariables as any, + })) as AsyncIterableIterator; const onDataPromise = results.next().then(async ({ value }) => { options.onSubscribedData(value.data); }); - await execute(schema, options.mutation, null, null, options.mutationVariables); + await execute({ + schema, + document: options.mutation, + variableValues: options.mutationVariables as any, + }); await onDataPromise; } @@ -331,7 +325,7 @@ describe("Subscriptions", () => { // run subscription in a separate async "thread" (async () => { for await (const result of subscription) { - subscriptionValue = result.data!.sampleTopicSubscription.value; + subscriptionValue = (result.data as any).sampleTopicSubscription.value; } })(); @@ -348,33 +342,6 @@ describe("Subscriptions", () => { expect(subscriptionValue).toEqual(4.53); }); - it("should successfully publish using Publisher injection", async () => { - let subscriptionValue: number; - const testedValue = Math.PI; - const subscription = gql` - subscription { - sampleTopicSubscription { - value - } - } - `; - const mutation = gql` - mutation { - pubSubPublisherMutation(value: ${testedValue}) - } - `; - - await subscribeOnceAndMutate({ - subscription, - mutation, - onSubscribedData: data => { - subscriptionValue = data.sampleTopicSubscription.value; - }, - }); - - expect(subscriptionValue!).toEqual(testedValue); - }); - it("should doesn't trigger subscription when published to other topic", async () => { let subscriptionValue!: number; const subscriptionQuery = gql` @@ -402,7 +369,7 @@ describe("Subscriptions", () => { // run subscription in a separate async "thread" (async () => { for await (const result of subscription) { - subscriptionValue = result.data!.sampleTopicSubscription.value; + subscriptionValue = (result.data as any).sampleTopicSubscription.value; } })(); @@ -441,7 +408,7 @@ describe("Subscriptions", () => { // run subscription in a separate async "thread" (async () => { for await (const result of subscription) { - subscriptionValue = result.data!.sampleTopicSubscriptionWithFilter.value; + subscriptionValue = (result.data as any).sampleTopicSubscriptionWithFilter.value; } })(); @@ -485,7 +452,7 @@ describe("Subscriptions", () => { // run subscription in a separate async "thread" (async () => { for await (const result of subscription) { - subscriptionValue = result.data!.multipleTopicSubscription.value; + subscriptionValue = (result.data as any).multipleTopicSubscription.value; } })(); @@ -557,102 +524,49 @@ describe("Subscriptions", () => { expect(subscriptionValue).toEqual(testedValue); }); + }); - it("should inject the provided custom PubSub implementation", async () => { - let pubSub: any; + describe("errors", () => { + it("should throw error when using subscriptions but not providing pub sub implementation", async () => { getMetadataStorage().clear(); + const error = await expectToThrow(async () => { + class SampleResolver { + @Query() + dumbQuery(): boolean { + return true; + } - @ObjectType() - class SampleObject { - @Field() - sampleField: string; - } - - class SampleResolver { - @Query() - dumbQuery(): boolean { - return true; - } - - @Mutation() - pubSubMutation(@PubSub() pubSubArg: any): boolean { - pubSub = pubSubArg; - return true; - } - } - const customPubSub = { myField: true }; - const mutation = `mutation { - pubSubMutation - }`; - - const localSchema = await buildSchema({ - resolvers: [SampleResolver], - pubSub: customPubSub as any, - }); - - await graphql(localSchema, mutation); - - expect(pubSub).toEqual(customPubSub); - expect(pubSub.myField).toEqual(true); - }); - - it("should create PubSub instance with provided emitter options", async () => { - getMetadataStorage().clear(); - @ObjectType() - class SampleObject { - @Field() - sampleField: string; - } - class SampleResolver { - @Query() - dumbQuery(): boolean { - return true; - } - @Mutation() - pubSubMutation(@PubSub() pubSubArg: PubSubEngine): boolean { - pubSubArg.publish("TEST", { test: true }); - return true; + @Subscription({ topics: "TEST" }) + sampleSubscription(): boolean { + return true; + } } - } - let emittedValue: any; - const customEmitter = new EventEmitter(); - customEmitter.on("TEST", payload => (emittedValue = payload)); - const mutation = `mutation { - pubSubMutation - }`; - const localSchema = await buildSchema({ - resolvers: [SampleResolver], - pubSub: { eventEmitter: customEmitter }, + await buildSchema({ + resolvers: [SampleResolver], + pubSub: undefined, + }); }); - await graphql(localSchema, mutation); - expect(emittedValue).toBeDefined(); - expect(emittedValue.test).toEqual(true); + expect(error).toBeDefined(); + expect(error).toBeInstanceOf(MissingPubSubError); }); it("should throw error while passing empty topics array to Subscription", async () => { getMetadataStorage().clear(); - expect.assertions(5); - try { - @ObjectType() - class SampleObject { - @Field() - sampleField: string; - } + const error = await expectToThrow(async () => { class SampleResolver { @Query() dumbQuery(): boolean { return true; } - @Mutation(returns => Boolean) - async pubSubMutation( - @Arg("value") value: number, - @PubSub() pubSub: PubSubEngine, - ): Promise { - await pubSub.publish("TEST", value); + + @Mutation(() => Boolean) + async pubSubMutation(@Arg("value") value: number): Promise { + pubSub.publish("TEST", value); return true; } + @Subscription({ topics: [] }) sampleSubscription(): boolean { return true; @@ -661,19 +575,20 @@ describe("Subscriptions", () => { await buildSchema({ resolvers: [SampleResolver], + pubSub, }); - } catch (err) { - expect(err).toBeDefined(); - expect(err).toBeInstanceOf(MissingSubscriptionTopicsError); - expect(err.message).toContain("SampleResolver"); - expect(err.message).toContain("sampleSubscription"); - expect(err.message).not.toContain("class SampleResolver"); - } + }); + + expect(error).toBeDefined(); + expect(error).toBeInstanceOf(MissingSubscriptionTopicsError); + expect(error.message).toContain("SampleResolver"); + expect(error.message).toContain("sampleSubscription"); + expect(error.message).not.toContain("class SampleResolver"); }); it("should throw authorization error just on subscribe", async () => { getMetadataStorage().clear(); - expect.assertions(3); + // expect.assertions(3); @Resolver() class SampleResolver { @@ -688,8 +603,9 @@ describe("Subscriptions", () => { return 0; } } - schema = await buildSchema({ + const schema = await buildSchema({ resolvers: [SampleResolver], + pubSub, authChecker: () => false, }); const document = gql` @@ -698,7 +614,7 @@ describe("Subscriptions", () => { } `; - const subscribeResult = await subscribe(schema, document); + const subscribeResult = await subscribe({ schema, document }); expect(subscribeResult).toHaveProperty("errors"); const { errors } = subscribeResult as ExecutionResult; diff --git a/tests/functional/typedefs-resolvers.ts b/tests/functional/typedefs-resolvers.ts index 685c68d1b..32bd90fa2 100644 --- a/tests/functional/typedefs-resolvers.ts +++ b/tests/functional/typedefs-resolvers.ts @@ -1,51 +1,52 @@ +/* eslint "no-underscore-dangle": ["error", { "allow": ["__schema"] }] */ import "reflect-metadata"; +import { makeExecutableSchema } from "@graphql-tools/schema"; +import { createPubSub } from "@graphql-yoga/subscription"; +import { MinLength } from "class-validator"; import { - IntrospectionSchema, - graphql, - getIntrospectionQuery, - IntrospectionQuery, - IntrospectionInterfaceType, + type ExecutionResult, + type GraphQLSchema, + type IntrospectionEnumType, + type IntrospectionInputObjectType, + type IntrospectionInterfaceType, + type IntrospectionNamedTypeRef, + type IntrospectionObjectType, + type IntrospectionQuery, + type IntrospectionScalarType, + type IntrospectionSchema, + type IntrospectionUnionType, TypeKind, - IntrospectionObjectType, - IntrospectionInputObjectType, - IntrospectionNamedTypeRef, - IntrospectionEnumType, - IntrospectionUnionType, - IntrospectionScalarType, execute, - GraphQLSchema, + getIntrospectionQuery, + graphql, subscribe, - ExecutionResult, } from "graphql"; -import { makeExecutableSchema } from "graphql-tools"; -import { PubSub } from "graphql-subscriptions"; -import { MinLength } from "class-validator"; -import Container, { Service } from "typedi"; import gql from "graphql-tag"; - -import { getMetadataStorage } from "../../src/metadata/getMetadataStorage"; import { - Resolver, - Query, - buildTypeDefsAndResolvers, - buildTypeDefsAndResolversSync, - InterfaceType, - ObjectType, - Field, - registerEnumType, - Subscription, - PubSubEngine, Arg, - createUnionType, + Authorized, + Field, + FieldResolver, + InputType, + InterfaceType, Mutation, + ObjectType, + type PubSub, + Query, + Resolver, + type ResolverObject, + type ResolverOptions, + type ResolversMap, Root, - InputType, - Authorized, + Subscription, UseMiddleware, - ResolversMap, - ResolverObject, - ResolverOptions, -} from "../../src"; + buildTypeDefsAndResolvers, + buildTypeDefsAndResolversSync, + createUnionType, + registerEnumType, +} from "type-graphql"; +import Container, { Service } from "typedi"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; describe("typeDefs and resolvers", () => { describe("buildTypeDefsAndResolvers", () => { @@ -54,7 +55,7 @@ describe("typeDefs and resolvers", () => { let resolvers: ResolversMap; let schemaIntrospection: IntrospectionSchema; let schema: GraphQLSchema; - let pubSub: PubSubEngine; + let pubSub: PubSub; let inputValue: any; let enumValue: any; let middlewareLogs: string[]; @@ -77,38 +78,51 @@ describe("typeDefs and resolvers", () => { @InterfaceType() abstract class SampleInterface { @Field() - sampleInterfaceStringField: string; + sampleInterfaceStringField!: string; } @ObjectType({ implements: SampleInterface }) class SampleType1 implements SampleInterface { @Field() - sampleInterfaceStringField: string; + sampleInterfaceStringField!: string; + @Field({ description: "sampleType1StringFieldDescription" }) - sampleType1StringField: string; + sampleType1StringField!: string; } @ObjectType({ implements: SampleInterface }) class SampleType2 implements SampleInterface { @Field() - sampleInterfaceStringField: string; + sampleInterfaceStringField!: string; + @Field({ deprecationReason: "sampleType2StringFieldDeprecation" }) - sampleType2StringField: string; + sampleType2StringField!: string; } @ObjectType() class SampleType3 { @Field() - sampleInterfaceStringField: string; + sampleInterfaceStringField!: string; + + @Field() + sampleType3StringField!: string; + } + + @ObjectType("SampleType__4") + class SampleType4 { + @Field() + sampleInterfaceStringField!: string; + @Field() - sampleType3StringField: string; + sampleType4StringField!: string; } @InputType() class SampleInput { @Field() @MinLength(10) - sampleInputStringField: string; + sampleInputStringField!: string; + @Field() sampleInputDefaultStringField: string = "sampleInputDefaultStringField"; } @@ -141,7 +155,7 @@ describe("typeDefs and resolvers", () => { if ("sampleType3StringField" in value) { return "SampleType3"; } - return; + return undefined; }, }); @@ -195,7 +209,7 @@ describe("typeDefs and resolvers", () => { return type1; } - @Query(returns => SampleUnion) + @Query(() => SampleUnion) sampleUnionQuery(): typeof SampleUnion { const type3 = new SampleType3(); type3.sampleInterfaceStringField = "sampleInterfaceStringField"; @@ -204,7 +218,7 @@ describe("typeDefs and resolvers", () => { return type3; } - @Query(returns => SampleResolveUnion) + @Query(() => SampleResolveUnion) sampleResolveUnionQuery(): typeof SampleResolveUnion { return { sampleInterfaceStringField: "sampleInterfaceStringField", @@ -212,17 +226,17 @@ describe("typeDefs and resolvers", () => { }; } - @Query(returns => SampleNumberEnum) + @Query(() => SampleNumberEnum) sampleNumberEnumQuery( - @Arg("numberEnum", type => SampleNumberEnum) numberEnum: SampleNumberEnum, + @Arg("numberEnum", () => SampleNumberEnum) numberEnum: SampleNumberEnum, ): SampleNumberEnum { enumValue = numberEnum; return numberEnum; } - @Query(returns => SampleStringEnum) + @Query(() => SampleStringEnum) sampleStringEnumQuery( - @Arg("stringEnum", type => SampleStringEnum) stringEnum: SampleStringEnum, + @Arg("stringEnum", () => SampleStringEnum) stringEnum: SampleStringEnum, ): SampleStringEnum { enumValue = stringEnum; return stringEnum; @@ -236,20 +250,39 @@ describe("typeDefs and resolvers", () => { } } - pubSub = new PubSub(); + pubSub = createPubSub(); + + @Service() + @Resolver(() => SampleType4) + class SampleObjectTypeWithDoubleUnderscoreInNameResolver { + @FieldResolver(() => String) + sampleResolvedField(): string { + return "sampleResolvedField"; + } + + @Query(() => SampleType4) + async sampleQueryOnObjectTypeWithDoubleUnderScore(): Promise { + const type4 = new SampleType4(); + type4.sampleInterfaceStringField = "sampleInterfaceStringField"; + type4.sampleType4StringField = "sampleType4StringField"; + return type4; + } + } + ({ typeDefs, resolvers } = await buildTypeDefsAndResolvers({ - resolvers: [SampleResolver], + resolvers: [SampleResolver, SampleObjectTypeWithDoubleUnderscoreInNameResolver], authChecker: () => false, pubSub, container: Container, orphanedTypes: [SampleType1], + validate: true, })); schema = makeExecutableSchema({ typeDefs, resolvers, }); - const introspectionResult = await graphql(schema, getIntrospectionQuery()); - schemaIntrospection = (introspectionResult.data as IntrospectionQuery).__schema; + const introspectionResult = await graphql({ schema, source: getIntrospectionQuery() }); + schemaIntrospection = (introspectionResult.data as unknown as IntrospectionQuery).__schema; }); it("should generate schema without errors", () => { @@ -281,6 +314,10 @@ describe("typeDefs and resolvers", () => { const sampleType2 = schemaIntrospection.types.find( it => it.name === "SampleType2", ) as IntrospectionObjectType; + const sampleType4 = schemaIntrospection.types.find( + it => it.name === "SampleType__4", + ) as IntrospectionObjectType; + const sampleType1StringField = sampleType1.fields.find( it => it.name === "sampleType1StringField", )!; @@ -294,6 +331,7 @@ describe("typeDefs and resolvers", () => { expect(sampleType1.interfaces).toHaveLength(1); expect(sampleType1.interfaces[0].name).toBe("SampleInterface"); expect(sampleType2StringField.deprecationReason).toBe("sampleType2StringFieldDeprecation"); + expect(sampleType4.fields).toHaveLength(3); }); it("should generate input type", async () => { @@ -303,7 +341,8 @@ describe("typeDefs and resolvers", () => { const sampleInputDefaultStringField = sampleInput.inputFields.find( it => it.name === "sampleInputDefaultStringField", )!; - const sampleInputDefaultStringFieldType = sampleInputDefaultStringField.type as IntrospectionNamedTypeRef; + const sampleInputDefaultStringFieldType = + sampleInputDefaultStringField.type as IntrospectionNamedTypeRef; expect(sampleInput.kind).toBe(TypeKind.INPUT_OBJECT); expect(sampleInput.inputFields).toHaveLength(2); @@ -350,7 +389,7 @@ describe("typeDefs and resolvers", () => { it => it.name === schemaIntrospection.queryType.name, ) as IntrospectionObjectType; - expect(queryType.fields).toHaveLength(8); + expect(queryType.fields).toHaveLength(9); }); it("should generate mutations", async () => { @@ -371,7 +410,7 @@ describe("typeDefs and resolvers", () => { it("should emit Date scalar", async () => { const dateScalar = schemaIntrospection.types.find( - it => it.name === "DateTime", + it => it.name === "DateTimeISO", ) as IntrospectionScalarType; expect(dateScalar.kind).toBe(TypeKind.SCALAR); @@ -396,10 +435,10 @@ describe("typeDefs and resolvers", () => { } `; - const { data } = await execute(schema, document); - const parsedDate = new Date(data!.sampleDateQuery); + const result: any = await execute({ schema, document }); + const parsedDate = new Date(result.data.sampleDateQuery); - expect(typeof data!.sampleDateQuery).toBe("string"); + expect(typeof result.data.sampleDateQuery).toBe("string"); expect(parsedDate.getTime()).toEqual(timestamp); }); @@ -410,7 +449,7 @@ describe("typeDefs and resolvers", () => { } `; - const { data } = await execute(schema, document); + const { data } = await execute({ schema, document }); expect(data!.sampleServiceQuery).toEqual("SampleString"); }); @@ -422,7 +461,7 @@ describe("typeDefs and resolvers", () => { } `; - const { data } = await execute(schema, document); + const { data } = await execute({ schema, document }); expect(data!.sampleMiddlewareBooleanQuery).toEqual(true); expect(middlewareLogs).toHaveLength(1); @@ -436,7 +475,7 @@ describe("typeDefs and resolvers", () => { } `; - const { data } = await execute(schema, document); + const { data } = await execute({ schema, document }); expect(data!.sampleBooleanMutation).toBe(true); }); @@ -448,7 +487,7 @@ describe("typeDefs and resolvers", () => { } `; - const { data } = await execute(schema, document); + const { data } = await execute({ schema, document }); expect(data!.sampleMutationWithInput).toBe(true); expect(inputValue.constructor.name).toBe("SampleInput"); @@ -463,7 +502,7 @@ describe("typeDefs and resolvers", () => { } `; - const { errors } = await execute(schema, document); + const { errors } = await execute({ schema, document }); expect(errors).toHaveLength(1); expect(errors![0].message).toContain("Argument Validation Error"); @@ -476,7 +515,7 @@ describe("typeDefs and resolvers", () => { } `; - const { errors } = await execute(schema, document); + const { errors } = await execute({ schema, document }); expect(errors).toHaveLength(1); expect(errors![0].message).toContain("Access denied"); @@ -494,7 +533,7 @@ describe("typeDefs and resolvers", () => { } `; - const { data } = await execute(schema, document); + const { data } = await execute({ schema, document }); expect(data!.sampleInterfaceQuery).toEqual({ sampleInterfaceStringField: "sampleInterfaceStringField", @@ -514,7 +553,7 @@ describe("typeDefs and resolvers", () => { } `; - const { data } = await execute(schema, document); + const { data } = await execute({ schema, document }); expect(data!.sampleUnionQuery).toEqual({ sampleInterfaceStringField: "sampleInterfaceStringField", @@ -534,7 +573,7 @@ describe("typeDefs and resolvers", () => { } `; - const { data } = await execute(schema, document); + const { data } = await execute({ schema, document }); expect(data!.sampleResolveUnionQuery).toEqual({ sampleInterfaceStringField: "sampleInterfaceStringField", @@ -549,7 +588,7 @@ describe("typeDefs and resolvers", () => { } `; - const { data } = await execute(schema, document); + const { data } = await execute({ schema, document }); expect(data!.sampleNumberEnumQuery).toBe("OptionOne"); expect(enumValue).toBe(0); @@ -562,12 +601,32 @@ describe("typeDefs and resolvers", () => { } `; - const { data } = await execute(schema, document); + const { data } = await execute({ schema, document }); expect(data!.sampleStringEnumQuery).toBe("OptionTwo"); expect(enumValue).toBe("OptionTwoString"); }); + it("should properly execute field resolver for object type with two underscores NOT in the beginning", async () => { + const document = gql` + query { + sampleQueryOnObjectTypeWithDoubleUnderScore { + sampleResolvedField + sampleInterfaceStringField + sampleType4StringField + } + } + `; + + const { data } = await execute({ schema, document }); + + expect(data!.sampleQueryOnObjectTypeWithDoubleUnderScore).toEqual({ + sampleResolvedField: "sampleResolvedField", + sampleInterfaceStringField: "sampleInterfaceStringField", + sampleType4StringField: "sampleType4StringField", + }); + }); + it("should properly run subscriptions", async () => { const document = gql` subscription { @@ -576,7 +635,7 @@ describe("typeDefs and resolvers", () => { `; const payload = 5.4321; - const iterator = (await subscribe(schema, document)) as AsyncIterator; + const iterator = (await subscribe({ schema, document })) as AsyncIterator; const firstValuePromise = iterator.next(); pubSub.publish("SAMPLE", payload); const data = await firstValuePromise; @@ -615,9 +674,10 @@ describe("typeDefs and resolvers", () => { @ObjectType() class SampleType { @Field() - sampleInterfaceStringField: string; + sampleInterfaceStringField!: string; + @Field({ description: "sampleTypeStringFieldDescription" }) - sampleTypeStringField: string; + sampleTypeStringField!: string; } @Resolver() @@ -637,8 +697,8 @@ describe("typeDefs and resolvers", () => { typeDefs, resolvers, }); - const introspectionResult = await graphql(schema, getIntrospectionQuery()); - schemaIntrospection = (introspectionResult.data as IntrospectionQuery).__schema; + const introspectionResult = await graphql({ schema, source: getIntrospectionQuery() }); + schemaIntrospection = (introspectionResult.data as unknown as IntrospectionQuery).__schema; }); it("should generate schema without errors", () => { @@ -677,7 +737,7 @@ describe("typeDefs and resolvers", () => { } `; - const { data, errors } = await execute(schema, document); + const { data, errors } = await execute({ schema, document }); expect(errors).toBeUndefined(); expect(data!.sampleBooleanQuery).toBe(true); diff --git a/tests/functional/unions.ts b/tests/functional/unions.ts index 1e1e3b249..49e1ed306 100644 --- a/tests/functional/unions.ts +++ b/tests/functional/unions.ts @@ -1,17 +1,17 @@ +/* eslint "no-underscore-dangle": ["error", { "allow": ["__typename"] }] */ import "reflect-metadata"; import { - IntrospectionSchema, - IntrospectionObjectType, - graphql, - GraphQLSchema, - IntrospectionUnionType, + type GraphQLSchema, + type IntrospectionObjectType, + type IntrospectionSchema, + type IntrospectionUnionType, TypeKind, + graphql, } from "graphql"; - +import { Field, ObjectType, Query, Resolver, buildSchema, createUnionType } from "type-graphql"; +import { getMetadataStorage } from "@/metadata/getMetadataStorage"; +import { getInnerFieldType, getInnerTypeOfNonNullableType } from "../helpers/getInnerFieldType"; import { getSchemaInfo } from "../helpers/getSchemaInfo"; -import { getInnerTypeOfNonNullableType, getInnerFieldType } from "../helpers/getInnerFieldType"; -import { getMetadataStorage } from "../../src/metadata/getMetadataStorage"; -import { Field, ObjectType, Query, createUnionType, buildSchema, Resolver } from "../../src"; describe("Unions", () => { let schemaIntrospection: IntrospectionSchema; @@ -24,17 +24,17 @@ describe("Unions", () => { @ObjectType() class ObjectOne { @Field() - fieldOne: string; + fieldOne!: string; } @ObjectType() class ObjectTwo { @Field() - fieldTwo: string; + fieldTwo!: string; } @ObjectType() class ObjectThree { @Field() - fieldThree: string; + fieldThree!: string; } const OneTwoThreeUnion = createUnionType({ @@ -58,7 +58,7 @@ describe("Unions", () => { if ("fieldTwo" in value) { return "ObjectTwo"; } - return; + return undefined; }, }); @@ -72,25 +72,25 @@ describe("Unions", () => { if ("fieldTwo" in value) { return ObjectTwo; } - return; + return undefined; }, }); @ObjectType() class ObjectUnion { - @Field(type => OneTwoThreeUnion) - unionField: typeof OneTwoThreeUnion; + @Field(() => OneTwoThreeUnion) + unionField!: typeof OneTwoThreeUnion; } class SampleResolver { - @Query(returns => OneTwoThreeUnion) + @Query(() => OneTwoThreeUnion) getObjectOneFromUnion(): typeof OneTwoThreeUnion { const oneInstance = new ObjectTwo(); oneInstance.fieldTwo = "fieldTwo"; return oneInstance; } - @Query(returns => OneTwoThreeUnionFn) + @Query(() => OneTwoThreeUnionFn) getObjectOneFromUnionFn(): typeof OneTwoThreeUnionFn { const oneInstance = new ObjectTwo(); oneInstance.fieldTwo = "fieldTwo"; @@ -106,21 +106,21 @@ describe("Unions", () => { }; } - @Query(returns => OneTwoThreeUnion) + @Query(() => OneTwoThreeUnion) getPlainObjectFromUnion(): typeof OneTwoThreeUnion { return { fieldTwo: "fieldTwo", }; } - @Query(returns => UnionWithStringResolveType) + @Query(() => UnionWithStringResolveType) getObjectOneFromStringResolveTypeUnion(): typeof UnionWithStringResolveType { return { fieldTwo: "fieldTwo", }; } - @Query(returns => UnionWithClassResolveType) + @Query(() => UnionWithClassResolveType) getObjectOneFromClassResolveTypeUnion(): typeof UnionWithClassResolveType { return { fieldTwo: "fieldTwo", @@ -216,7 +216,7 @@ describe("Unions", () => { } }`; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); const data = result.data!.getObjectOneFromUnion; expect(data.__typename).toEqual("ObjectTwo"); expect(data.fieldTwo).toEqual("fieldTwo"); @@ -236,7 +236,7 @@ describe("Unions", () => { } }`; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); const data = result.data!.getObjectOneFromStringResolveTypeUnion; expect(data.__typename).toEqual("ObjectTwo"); expect(data.fieldTwo).toEqual("fieldTwo"); @@ -256,7 +256,7 @@ describe("Unions", () => { } }`; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); const data = result.data!.getObjectOneFromClassResolveTypeUnion; expect(data.__typename).toEqual("ObjectTwo"); expect(data.fieldTwo).toEqual("fieldTwo"); @@ -278,7 +278,7 @@ describe("Unions", () => { } }`; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); const unionFieldData = result.data!.getObjectWithUnion.unionField; expect(unionFieldData.__typename).toEqual("ObjectTwo"); @@ -299,7 +299,7 @@ describe("Unions", () => { } }`; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); expect(result.data).toBeNull(); expect(result.errors).toHaveLength(1); @@ -317,37 +317,36 @@ describe("Unions", () => { @ObjectType() class Base { @Field() - base: string; + base!: string; } @ObjectType() class Extended extends Base { @Field() - extended: string; + extended!: string; } - const ExtendedBase = createUnionType({ - name: "ExtendedBase", - types: () => [Base, Extended] as const, - }); - const _extended: typeof ExtendedBase = { - base: "base", - extended: "extended", - }; + + expect(() => { + createUnionType({ + name: "ExtendedBase", + types: () => [Base, Extended] as const, + }); + }).not.toThrow(); }); }); - describe("Mutliple schemas", () => { + describe("Multiple schemas", () => { it("should correctly return data from union query for all schemas that uses the same union", async () => { getMetadataStorage().clear(); @ObjectType() class One { @Field() - one: string; + one!: string; } @ObjectType() class Two { @Field() - two: string; + two!: string; } const OneTwo = createUnionType({ name: "OneTwo", @@ -355,7 +354,7 @@ describe("Unions", () => { }); @Resolver() class OneTwoResolver { - @Query(returns => OneTwo) + @Query(() => OneTwo) oneTwo(): typeof OneTwo { const one = new One(); one.one = "one"; @@ -382,8 +381,8 @@ describe("Unions", () => { const secondSchema = await buildSchema({ resolvers: [OneTwoResolver], }); - const firstResult = await graphql(firstSchema, query); - const secondResult = await graphql(secondSchema, query); + const firstResult = await graphql({ schema: firstSchema, source: query }); + const secondResult = await graphql({ schema: secondSchema, source: query }); expect(firstResult.errors).toBeUndefined(); expect(firstResult.data!.oneTwo).toEqual({ @@ -403,12 +402,12 @@ describe("Unions", () => { @ObjectType() class One { @Field() - one: string; + one!: string; } @ObjectType() class Two { @Field() - two: string; + two!: string; } const OneTwo = createUnionType({ name: "OneTwo", @@ -425,7 +424,7 @@ describe("Unions", () => { }); @Resolver() class OneTwoResolver { - @Query(returns => OneTwo) + @Query(() => OneTwo) oneTwo(): typeof OneTwo { const one = new One(); one.one = "one"; @@ -452,8 +451,8 @@ describe("Unions", () => { const secondSchema = await buildSchema({ resolvers: [OneTwoResolver], }); - const firstResult = await graphql(firstSchema, query); - const secondResult = await graphql(secondSchema, query); + const firstResult = await graphql({ schema: firstSchema, source: query }); + const secondResult = await graphql({ schema: secondSchema, source: query }); expect(firstResult.errors).toBeUndefined(); expect(firstResult.data!.oneTwo).toEqual({ @@ -473,12 +472,12 @@ describe("Unions", () => { @ObjectType() class One { @Field() - one: string; + one!: string; } @ObjectType() class Two { @Field() - two: string; + two!: string; } const OneTwo = createUnionType({ name: "OneTwo", @@ -495,7 +494,7 @@ describe("Unions", () => { }); @Resolver() class OneTwoResolver { - @Query(returns => OneTwo) + @Query(() => OneTwo) oneTwo(): typeof OneTwo { const one = new One(); one.one = "one"; @@ -522,8 +521,8 @@ describe("Unions", () => { const secondSchema = await buildSchema({ resolvers: [OneTwoResolver], }); - const firstResult = await graphql(firstSchema, query); - const secondResult = await graphql(secondSchema, query); + const firstResult = await graphql({ schema: firstSchema, source: query }); + const secondResult = await graphql({ schema: secondSchema, source: query }); expect(firstResult.errors).toBeUndefined(); expect(firstResult.data!.oneTwo).toEqual({ @@ -543,23 +542,21 @@ describe("Unions", () => { @ObjectType() class One { @Field() - one: string; + one!: string; } @ObjectType() class Two { @Field() - two: string; + two!: string; } const OneTwo = createUnionType({ name: "OneTwo", types: () => [One, Two], - resolveType: () => { - return undefined; - }, + resolveType: () => undefined, }); @Resolver() class OneTwoResolver { - @Query(returns => OneTwo) + @Query(() => OneTwo) oneTwo(): typeof OneTwo { const one = new One(); one.one = "one"; @@ -583,10 +580,10 @@ describe("Unions", () => { const testSchema = await buildSchema({ resolvers: [OneTwoResolver], }); - const result = await graphql(testSchema, query); + const result: any = await graphql({ schema: testSchema, source: query }); expect(result.errors?.[0]?.message).toMatchInlineSnapshot( - `"Abstract type \\"OneTwo\\" must resolve to an Object type at runtime for field \\"Query.oneTwo\\". Either the \\"OneTwo\\" type should provide a \\"resolveType\\" function or each possible type should provide an \\"isTypeOf\\" function."`, + `"Abstract type "OneTwo" must resolve to an Object type at runtime for field "Query.oneTwo". Either the "OneTwo" type should provide a "resolveType" function or each possible type should provide an "isTypeOf" function."`, ); }); }); diff --git a/tests/functional/validation.ts b/tests/functional/validation.ts index d2805dc25..490cb2b40 100644 --- a/tests/functional/validation.ts +++ b/tests/functional/validation.ts @@ -1,29 +1,28 @@ import "reflect-metadata"; -import { MaxLength, Max, Min, ValidateNested } from "class-validator"; -import { GraphQLSchema, graphql } from "graphql"; - -import { getMetadataStorage } from "../../src/metadata/getMetadataStorage"; +import { Max, MaxLength, Min, ValidateNested } from "class-validator"; +import { type GraphQLSchema, graphql } from "graphql"; import { - InputType, - Field, - buildSchema, Arg, - ObjectType, - Resolver, - Mutation, - Query, - ArgumentValidationError, Args, ArgsType, -} from "../../src"; -import { TypeValue } from "../../src/decorators/types"; + ArgumentValidationError, + Field, + InputType, + Mutation, + ObjectType, + Query, + Resolver, + type ResolverData, + buildSchema, + getMetadataStorage, +} from "type-graphql"; +import { type TypeValue } from "@/decorators/types"; describe("Validation", () => { describe("Functional", () => { let schema: GraphQLSchema; let argInput: any; let argsData: any; - let sampleResolver: any; beforeEach(() => { argInput = undefined; @@ -43,21 +42,21 @@ describe("Validation", () => { class SampleInput { @Field() @MaxLength(5) - stringField: string; + stringField!: string; @Field() @Max(5) - numberField: number; + numberField!: number; @Field({ nullable: true }) @Min(5) optionalField?: number; - @Field(type => SampleInput, { nullable: true }) + @Field(() => SampleInput, { nullable: true }) @ValidateNested() nestedField?: SampleInput; - @Field(type => [SampleInput], { nullable: true }) + @Field(() => [SampleInput], { nullable: true }) @ValidateNested({ each: true }) arrayField?: SampleInput[]; } @@ -66,18 +65,18 @@ describe("Validation", () => { class SampleArguments { @Field() @MaxLength(5) - stringField: string; + stringField!: string; @Field() @Max(5) - numberField: number; + numberField!: number; @Field({ nullable: true }) @Min(5) optionalField?: number; } - @Resolver(of => SampleObject) + @Resolver(() => SampleObject) class SampleResolver { @Query() sampleQuery(@Args() args: SampleArguments): SampleObject { @@ -93,13 +92,21 @@ describe("Validation", () => { @Mutation() mutationWithInputsArray( - @Arg("inputs", type => [SampleInput]) inputs: SampleInput[], + @Arg("inputs", () => [SampleInput]) inputs: SampleInput[], + ): SampleObject { + argInput = inputs; + return {}; + } + + @Mutation() + mutationWithOptionalInputsArray( + @Arg("inputs", () => [SampleInput], { nullable: "items" }) + inputs: Array, ): SampleObject { argInput = inputs; return {}; } } - sampleResolver = SampleResolver; schema = await buildSchema({ resolvers: [SampleResolver], @@ -116,7 +123,7 @@ describe("Validation", () => { field } }`; - await graphql(schema, mutation); + await graphql({ schema, source: mutation }); expect(argInput).toEqual({ stringField: "12345", numberField: 5 }); }); @@ -131,7 +138,7 @@ describe("Validation", () => { field } }`; - await graphql(schema, mutation); + await graphql({ schema, source: mutation }); expect(argInput).toEqual({ stringField: "12345", numberField: 5, optionalField: 5 }); }); @@ -146,14 +153,14 @@ describe("Validation", () => { } }`; - const result = await graphql(schema, mutation); + const result: any = await graphql({ schema, source: mutation }); expect(result.data).toBeNull(); expect(result.errors).toHaveLength(1); const validationError = result.errors![0].originalError! as ArgumentValidationError; expect(validationError).toBeInstanceOf(ArgumentValidationError); - expect(validationError.validationErrors).toHaveLength(1); - expect(validationError.validationErrors[0].property).toEqual("numberField"); + expect(validationError.extensions.validationErrors).toHaveLength(1); + expect(validationError.extensions.validationErrors[0].property).toEqual("numberField"); }); it("should throw validation error when nested input field is incorrect", async () => { @@ -170,14 +177,14 @@ describe("Validation", () => { } }`; - const result = await graphql(schema, mutation); + const result: any = await graphql({ schema, source: mutation }); expect(result.data).toBeNull(); expect(result.errors).toHaveLength(1); const validationError = result.errors![0].originalError! as ArgumentValidationError; expect(validationError).toBeInstanceOf(ArgumentValidationError); - expect(validationError.validationErrors).toHaveLength(1); - expect(validationError.validationErrors[0].property).toEqual("nestedField"); + expect(validationError.extensions.validationErrors).toHaveLength(1); + expect(validationError.extensions.validationErrors[0].property).toEqual("nestedField"); }); it("should throw validation error when nested array input field is incorrect", async () => { @@ -194,14 +201,14 @@ describe("Validation", () => { } }`; - const result = await graphql(schema, mutation); + const result: any = await graphql({ schema, source: mutation }); expect(result.data).toBeNull(); expect(result.errors).toHaveLength(1); const validationError = result.errors![0].originalError! as ArgumentValidationError; expect(validationError).toBeInstanceOf(ArgumentValidationError); - expect(validationError.validationErrors).toHaveLength(1); - expect(validationError.validationErrors[0].property).toEqual("arrayField"); + expect(validationError.extensions.validationErrors).toHaveLength(1); + expect(validationError.extensions.validationErrors[0].property).toEqual("arrayField"); }); it("should throw validation error when one of input array is incorrect", async () => { @@ -220,14 +227,59 @@ describe("Validation", () => { } }`; - const result = await graphql(schema, mutation); + const result: any = await graphql({ schema, source: mutation }); expect(result.data).toBeNull(); expect(result.errors).toHaveLength(1); const validationError = result.errors![0].originalError! as ArgumentValidationError; expect(validationError).toBeInstanceOf(ArgumentValidationError); - expect(validationError.validationErrors).toHaveLength(1); - expect(validationError.validationErrors[0].property).toEqual("numberField"); + expect(validationError.extensions.validationErrors).toHaveLength(1); + expect(validationError.extensions.validationErrors[0].property).toEqual("numberField"); + }); + + it("should not throw error when one of optional items in the input array is null", async () => { + const mutation = `mutation { + mutationWithOptionalInputsArray(inputs: [ + null, + { + stringField: "12345", + numberField: 5 + }, + ]) { + field + } + }`; + + const result = await graphql({ schema, source: mutation }); + expect(result.errors).toBeUndefined(); + expect(result.data).toEqual({ mutationWithOptionalInputsArray: { field: null } }); + }); + + it("should properly validate arg array when one of optional items in the input array is incorrect", async () => { + const mutation = `mutation { + mutationWithOptionalInputsArray(inputs: [ + null, + { + stringField: "12345", + numberField: 5 + }, + { + stringField: "12345", + numberField: 15, + }, + ]) { + field + } + }`; + + const result = await graphql({ schema, source: mutation }); + expect(result.data).toBeNull(); + expect(result.errors).toHaveLength(1); + + const validationError = result.errors![0].originalError! as ArgumentValidationError; + expect(validationError).toBeInstanceOf(ArgumentValidationError); + expect(validationError.extensions.validationErrors).toHaveLength(1); + expect(validationError.extensions.validationErrors[0].property).toEqual("numberField"); }); it("should throw validation error when optional input field is incorrect", async () => { @@ -241,14 +293,14 @@ describe("Validation", () => { } }`; - const result = await graphql(schema, mutation); + const result: any = await graphql({ schema, source: mutation }); expect(result.data).toBeNull(); expect(result.errors).toHaveLength(1); const validationError = result.errors![0].originalError! as ArgumentValidationError; expect(validationError).toBeInstanceOf(ArgumentValidationError); - expect(validationError.validationErrors).toHaveLength(1); - expect(validationError.validationErrors[0].property).toEqual("optionalField"); + expect(validationError.extensions.validationErrors).toHaveLength(1); + expect(validationError.extensions.validationErrors[0].property).toEqual("optionalField"); }); it("should pass input validation when arguments data without optional field is correct", async () => { @@ -260,7 +312,7 @@ describe("Validation", () => { field } }`; - await graphql(schema, query); + await graphql({ schema, source: query }); expect(argsData).toEqual({ stringField: "12345", numberField: 5 }); }); @@ -275,7 +327,7 @@ describe("Validation", () => { field } }`; - await graphql(schema, query); + await graphql({ schema, source: query }); expect(argsData).toEqual({ stringField: "12345", numberField: 5, optionalField: 5 }); }); @@ -290,14 +342,14 @@ describe("Validation", () => { } }`; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); expect(result.data).toBeNull(); expect(result.errors).toHaveLength(1); const validationError = result.errors![0].originalError! as ArgumentValidationError; expect(validationError).toBeInstanceOf(ArgumentValidationError); - expect(validationError.validationErrors).toHaveLength(1); - expect(validationError.validationErrors[0].property).toEqual("numberField"); + expect(validationError.extensions.validationErrors).toHaveLength(1); + expect(validationError.extensions.validationErrors[0].property).toEqual("numberField"); }); it("should throw validation error when optional argument is incorrect", async () => { @@ -311,14 +363,14 @@ describe("Validation", () => { } }`; - const result = await graphql(schema, query); + const result: any = await graphql({ schema, source: query }); expect(result.data).toBeNull(); expect(result.errors).toHaveLength(1); const validationError = result.errors![0].originalError! as ArgumentValidationError; expect(validationError).toBeInstanceOf(ArgumentValidationError); - expect(validationError.validationErrors).toHaveLength(1); - expect(validationError.validationErrors[0].property).toEqual("optionalField"); + expect(validationError.extensions.validationErrors).toHaveLength(1); + expect(validationError.extensions.validationErrors[0].property).toEqual("optionalField"); }); }); @@ -328,7 +380,7 @@ describe("Validation", () => { localArgsData = undefined; }); - it("should pass incorrect args when validation is turned off", async () => { + it("should pass incorrect args when validation is turned off by default", async () => { getMetadataStorage().clear(); @ObjectType() @@ -340,9 +392,47 @@ describe("Validation", () => { class SampleArguments { @Field() @MaxLength(5) - field: string; + field!: string; } - @Resolver(of => SampleObject) + @Resolver(() => SampleObject) + class SampleResolver { + @Query() + sampleQuery(@Args() args: SampleArguments): SampleObject { + localArgsData = args; + return {}; + } + } + const localSchema = await buildSchema({ + resolvers: [SampleResolver], + // default - `validate: false,` + }); + + const query = `query { + sampleQuery( + field: "12345678", + ) { + field + } + }`; + await graphql({ schema: localSchema, source: query }); + expect(localArgsData).toEqual({ field: "12345678" }); + }); + + it("should pass incorrect args when validation is turned off explicitly", async () => { + getMetadataStorage().clear(); + + @ObjectType() + class SampleObject { + @Field({ nullable: true }) + field?: string; + } + @ArgsType() + class SampleArguments { + @Field() + @MaxLength(5) + field!: string; + } + @Resolver(() => SampleObject) class SampleResolver { @Query() sampleQuery(@Args() args: SampleArguments): SampleObject { @@ -362,7 +452,7 @@ describe("Validation", () => { field } }`; - await graphql(localSchema, query); + await graphql({ schema: localSchema, source: query }); expect(localArgsData).toEqual({ field: "12345678" }); }); @@ -378,9 +468,9 @@ describe("Validation", () => { class SampleArguments { @Field() @MaxLength(5) - field: string; + field!: string; } - @Resolver(of => SampleObject) + @Resolver(() => SampleObject) class SampleResolver { @Query() sampleQuery(@Args({ validate: false }) args: SampleArguments): SampleObject { @@ -400,7 +490,7 @@ describe("Validation", () => { field } }`; - await graphql(localSchema, query); + await graphql({ schema: localSchema, source: query }); expect(localArgsData).toEqual({ field: "12345678" }); }); @@ -416,9 +506,9 @@ describe("Validation", () => { class SampleArguments { @Field() @MaxLength(5) - field: string; + field!: string; } - @Resolver(of => SampleObject) + @Resolver(() => SampleObject) class SampleResolver { @Query() sampleQuery(@Args({ validate: true }) args: SampleArguments): SampleObject { @@ -438,14 +528,14 @@ describe("Validation", () => { field } }`; - const result = await graphql(localSchema, query); + const result: any = await graphql({ schema: localSchema, source: query }); expect(result.data).toBeNull(); expect(result.errors).toHaveLength(1); const validationError = result.errors![0].originalError! as ArgumentValidationError; expect(validationError).toBeInstanceOf(ArgumentValidationError); - expect(validationError.validationErrors).toHaveLength(1); - expect(validationError.validationErrors[0].property).toEqual("field"); + expect(validationError.extensions.validationErrors).toHaveLength(1); + expect(validationError.extensions.validationErrors[0].property).toEqual("field"); }); it("should throw validation error for incorrect args when applied local validation settings", async () => { @@ -460,9 +550,9 @@ describe("Validation", () => { class SampleArguments { @Field() @MaxLength(5, { groups: ["test"] }) - field: string; + field!: string; } - @Resolver(of => SampleObject) + @Resolver(() => SampleObject) class SampleResolver { @Query() sampleQuery(@Args({ validate: { groups: ["test"] } }) args: SampleArguments): SampleObject { @@ -482,14 +572,14 @@ describe("Validation", () => { field } }`; - const result = await graphql(localSchema, query); + const result: any = await graphql({ schema: localSchema, source: query }); expect(result.data).toBeNull(); expect(result.errors).toHaveLength(1); const validationError = result.errors![0].originalError! as ArgumentValidationError; expect(validationError).toBeInstanceOf(ArgumentValidationError); - expect(validationError.validationErrors).toHaveLength(1); - expect(validationError.validationErrors[0].property).toEqual("field"); + expect(validationError.extensions.validationErrors).toHaveLength(1); + expect(validationError.extensions.validationErrors[0].property).toEqual("field"); }); it("should pass validation of incorrect args when applied local validation settings", async () => { @@ -504,9 +594,9 @@ describe("Validation", () => { class SampleArguments { @Field() @MaxLength(5, { groups: ["not-test"] }) - field: string; + field!: string; } - @Resolver(of => SampleObject) + @Resolver(() => SampleObject) class SampleResolver { @Query() sampleQuery(@Args({ validate: { groups: ["test"] } }) args: SampleArguments): SampleObject { @@ -526,7 +616,7 @@ describe("Validation", () => { field } }`; - await graphql(localSchema, query); + await graphql({ schema: localSchema, source: query }); expect(localArgsData).toEqual({ field: "123456789" }); }); @@ -542,9 +632,9 @@ describe("Validation", () => { class SampleArguments { @Field() @MaxLength(5, { groups: ["test"] }) - field: string; + field!: string; } - @Resolver(of => SampleObject) + @Resolver(() => SampleObject) class SampleResolver { @Query() sampleQuery(@Args({ validate: { groups: ["test"] } }) args: SampleArguments): SampleObject { @@ -564,11 +654,11 @@ describe("Validation", () => { field } }`; - const { errors } = await graphql(localSchema, query); + const { errors } = await graphql({ schema: localSchema, source: query }); const error = errors![0].originalError! as ArgumentValidationError; expect(localArgsData).toBeUndefined(); - expect(error.validationErrors[0].target).toBeUndefined(); + expect(error.extensions.validationErrors[0].target).toBeUndefined(); }); }); }); @@ -581,10 +671,12 @@ describe("Custom validation", () => { } `; let sampleArgsCls: Function; + let sampleInputCls: Function; let sampleResolverCls: Function; - let validateArgs: Array = []; + let validateArgs: Array = []; let validateTypes: TypeValue[] = []; + let validateResolverData: ResolverData[] = []; let sampleQueryArgs: any[] = []; beforeAll(async () => { @@ -596,13 +688,39 @@ describe("Custom validation", () => { sampleField!: string; } sampleArgsCls = SampleArgs; + @InputType() + class SampleInput { + @Field() + sampleField!: string; + } + sampleInputCls = SampleInput; @Resolver() class SampleResolver { - @Query(returns => Boolean) + @Query(() => Boolean) sampleQuery(@Args() args: SampleArgs) { sampleQueryArgs.push(args); return true; } + + @Query(() => Boolean) + sampleArrayArgQuery(@Arg("arrayArg", () => [SampleInput]) arrayArg: SampleInput[]) { + sampleQueryArgs.push(arrayArg); + return true; + } + + @Query() + sampleInlineArgValidateFnQuery( + @Arg("arg", { + validateFn: (arg, type, resolverData) => { + validateArgs.push(arg); + validateTypes.push(type); + validateResolverData.push(resolverData); + }, + }) + arg: SampleInput, + ): string { + return arg.sampleField; + } } sampleResolverCls = SampleResolver; }); @@ -610,47 +728,102 @@ describe("Custom validation", () => { beforeEach(() => { validateArgs = []; validateTypes = []; + validateResolverData = []; sampleQueryArgs = []; }); - it("should call `validate` function provided in option with proper params", async () => { + it("should call `validateFn` function provided in option with proper params", async () => { schema = await buildSchema({ resolvers: [sampleResolverCls], - validate: (arg, type) => { + validateFn: (arg, type, resolverData) => { validateArgs.push(arg); validateTypes.push(type); + validateResolverData.push(resolverData); }, }); - await graphql(schema, document); + await graphql({ schema, source: document, contextValue: { isContext: true } }); expect(validateArgs).toEqual([{ sampleField: "sampleFieldValue" }]); expect(validateArgs[0]).toBeInstanceOf(sampleArgsCls); expect(validateTypes).toEqual([sampleArgsCls]); + expect(validateResolverData).toEqual([ + expect.objectContaining({ + context: { isContext: true }, + }), + ]); + }); + + it("should let `validateFn` function handle array args", async () => { + schema = await buildSchema({ + resolvers: [sampleResolverCls], + validateFn: (arg, type) => { + validateArgs.push(arg); + validateTypes.push(type); + }, + }); + + await graphql({ + schema, + source: /* graphql */ ` + query { + sampleArrayArgQuery(arrayArg: [{ sampleField: "sampleFieldValue" }]) + } + `, + }); + + expect(validateArgs).toEqual([[{ sampleField: "sampleFieldValue" }]]); + expect((validateArgs[0] as object[])[0]).toBeInstanceOf(sampleInputCls); + expect(validateTypes).toEqual([sampleInputCls]); }); it("should inject validated arg as resolver param", async () => { schema = await buildSchema({ resolvers: [sampleResolverCls], - validate: () => { + validateFn: () => { // do nothing }, }); - await graphql(schema, document); + await graphql({ schema, source: document }); expect(sampleQueryArgs).toEqual([{ sampleField: "sampleFieldValue" }]); }); + it("should call `validateFn` function provided inline in arg option with proper params", async () => { + schema = await buildSchema({ + resolvers: [sampleResolverCls], + }); + + await graphql({ + schema, + source: /* graphql */ ` + query { + sampleInlineArgValidateFnQuery(arg: { sampleField: "sampleArgValue" }) + } + `, + contextValue: { isContext: true }, + }); + + expect(validateArgs).toEqual([{ sampleField: "sampleArgValue" }]); + expect(validateArgs[0]).toBeInstanceOf(sampleInputCls); + expect(validateTypes).toEqual([sampleInputCls]); + expect(validateResolverData).toEqual([ + expect.objectContaining({ + context: { isContext: true }, + }), + ]); + }); + it("should rethrow wrapped error when error thrown in `validate`", async () => { schema = await buildSchema({ resolvers: [sampleResolverCls], - validate: () => { + validateFn: () => { throw new Error("Test validate error"); }, }); - const result = await graphql(schema, document); + const result: any = await graphql({ schema, source: document }); expect(result.errors).toHaveLength(1); expect(result.errors![0].message).toEqual("Test validate error"); diff --git a/tests/helpers/circular-refs/good/CircularRef1.ts b/tests/helpers/circular-refs/good/CircularRef1.ts index ca6b910e9..068589146 100644 --- a/tests/helpers/circular-refs/good/CircularRef1.ts +++ b/tests/helpers/circular-refs/good/CircularRef1.ts @@ -1,18 +1,18 @@ -import { Field, ObjectType } from "../../../../src"; - +import { Field, ObjectType } from "type-graphql"; +// eslint-disable-next-line import/no-cycle import { CircularRef2 } from "./CircularRef2"; let hasModuleFinishedInitialLoad = false; @ObjectType() export class CircularRef1 { - @Field(type => { + @Field(() => { if (!hasModuleFinishedInitialLoad) { throw new Error("Field type function was called synchronously during module load"); } return [CircularRef2]; }) - ref2Field: any[]; + ref2Field!: any[]; } hasModuleFinishedInitialLoad = true; diff --git a/tests/helpers/circular-refs/good/CircularRef2.ts b/tests/helpers/circular-refs/good/CircularRef2.ts index faf588eea..165a67dc9 100644 --- a/tests/helpers/circular-refs/good/CircularRef2.ts +++ b/tests/helpers/circular-refs/good/CircularRef2.ts @@ -1,18 +1,18 @@ -import { Field, ObjectType } from "../../../../src"; - +import { Field, ObjectType } from "type-graphql"; +// eslint-disable-next-line import/no-cycle import { CircularRef1 } from "./CircularRef1"; let hasModuleFinishedInitialLoad = false; @ObjectType() export class CircularRef2 { - @Field(type => { + @Field(() => { if (!hasModuleFinishedInitialLoad) { throw new Error("Field type function was called synchronously during module load"); } return [CircularRef1]; }) - ref1Field: any[]; + ref1Field!: any[]; } hasModuleFinishedInitialLoad = true; diff --git a/tests/helpers/circular-refs/wrong/CircularRef1.ts b/tests/helpers/circular-refs/wrong/CircularRef1.ts index 1b7c133d2..0ce3a3eb6 100644 --- a/tests/helpers/circular-refs/wrong/CircularRef1.ts +++ b/tests/helpers/circular-refs/wrong/CircularRef1.ts @@ -1,9 +1,9 @@ -import { Field, ObjectType } from "../../../../src"; - +import { Field, ObjectType } from "type-graphql"; +// eslint-disable-next-line import/no-cycle import { CircularRef2 } from "./CircularRef2"; @ObjectType() export class CircularRef1 { @Field() - ref2Field: CircularRef2; + ref2Field!: CircularRef2; } diff --git a/tests/helpers/circular-refs/wrong/CircularRef2.ts b/tests/helpers/circular-refs/wrong/CircularRef2.ts index bc5d32ea1..da77b74c1 100644 --- a/tests/helpers/circular-refs/wrong/CircularRef2.ts +++ b/tests/helpers/circular-refs/wrong/CircularRef2.ts @@ -1,9 +1,9 @@ -import { Field, ObjectType } from "../../../../src"; - +import { Field, ObjectType } from "type-graphql"; +// eslint-disable-next-line import/no-cycle import { CircularRef1 } from "./CircularRef1"; @ObjectType() export class CircularRef2 { @Field() - ref1Field: CircularRef1; + ref1Field!: CircularRef1; } diff --git a/tests/helpers/customScalar.ts b/tests/helpers/customScalar.ts index 13eaf1fe3..9a78d69ac 100644 --- a/tests/helpers/customScalar.ts +++ b/tests/helpers/customScalar.ts @@ -6,6 +6,7 @@ export const CustomScalar = new GraphQLScalarType({ parseValue: () => "TypeGraphQL parseValue", serialize: () => "TypeGraphQL serialize", }); + export class CustomType {} export const ObjectScalar = new GraphQLScalarType({ @@ -16,5 +17,5 @@ export const ObjectScalar = new GraphQLScalarType({ parseValue: () => ({ value: "TypeGraphQL parseValue", }), - serialize: obj => obj.value, + serialize: (obj: any) => obj.value, }); diff --git a/tests/helpers/directives/AppendDirective.ts b/tests/helpers/directives/AppendDirective.ts deleted file mode 100644 index da8596b77..000000000 --- a/tests/helpers/directives/AppendDirective.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { SchemaDirectiveVisitor } from "graphql-tools"; -import { GraphQLField, GraphQLString, GraphQLDirective, DirectiveLocation } from "graphql"; - -export class AppendDirective extends SchemaDirectiveVisitor { - static getDirectiveDeclaration(directiveName: string): GraphQLDirective { - return new GraphQLDirective({ - name: directiveName, - locations: [DirectiveLocation.FIELD_DEFINITION], - }); - } - - visitFieldDefinition(field: GraphQLField) { - const resolve = field.resolve; - - field.args.push({ - name: "append", - description: "Appends a string to the end of a field", - type: GraphQLString, - defaultValue: "", - extensions: {}, - astNode: undefined, - deprecationReason: undefined, - }); - - field.resolve = async function (source, { append, ...otherArgs }, context, info) { - const result = await resolve!.call(this, source, otherArgs, context, info); - - return `${result}${append}`; - }; - } -} diff --git a/tests/helpers/directives/TestDirective.ts b/tests/helpers/directives/TestDirective.ts new file mode 100644 index 000000000..6e8dbe92e --- /dev/null +++ b/tests/helpers/directives/TestDirective.ts @@ -0,0 +1,119 @@ +import { MapperKind, getDirective, mapSchema } from "@graphql-tools/utils"; +import { + DirectiveLocation, + type GraphQLArgumentConfig, + GraphQLDirective, + type GraphQLFieldConfig, + type GraphQLInputFieldConfig, + GraphQLInputObjectType, + type GraphQLInputObjectTypeConfig, + GraphQLInterfaceType, + type GraphQLInterfaceTypeConfig, + GraphQLNonNull, + GraphQLObjectType, + type GraphQLObjectTypeConfig, + type GraphQLSchema, + GraphQLString, +} from "graphql"; + +function mapConfig< + TConfig extends + | GraphQLFieldConfig + | GraphQLObjectTypeConfig + | GraphQLInterfaceTypeConfig + | GraphQLInputObjectTypeConfig + | GraphQLInputFieldConfig + | GraphQLArgumentConfig, +>(config: TConfig) { + return { + ...config, + extensions: { + ...config.extensions, + TypeGraphQL: { + isMappedByDirective: true, + }, + }, + }; +} + +export const testDirective = new GraphQLDirective({ + name: "test", + args: { + argNonNullDefault: { + type: new GraphQLNonNull(GraphQLString), + defaultValue: "argNonNullDefault", + }, + argNullDefault: { + type: GraphQLString, + defaultValue: "argNullDefault", + }, + argNull: { + type: GraphQLString, + }, + }, + locations: [ + DirectiveLocation.OBJECT, + DirectiveLocation.FIELD_DEFINITION, + DirectiveLocation.INPUT_OBJECT, + DirectiveLocation.INPUT_FIELD_DEFINITION, + DirectiveLocation.INTERFACE, + DirectiveLocation.ARGUMENT_DEFINITION, + ], +}); + +export function testDirectiveTransformer(schema: GraphQLSchema): GraphQLSchema { + return mapSchema(schema, { + [MapperKind.OBJECT_TYPE]: typeInfo => { + const testDirectiveConfig = getDirective(schema, typeInfo, testDirective.name)?.[0]; + if (testDirectiveConfig) { + const config = typeInfo.toConfig(); + return new GraphQLObjectType(mapConfig(config)); + } + return typeInfo; + }, + [MapperKind.OBJECT_FIELD]: fieldConfig => { + const testDirectiveConfig = getDirective(schema, fieldConfig, testDirective.name)?.[0]; + if (testDirectiveConfig) { + return mapConfig(fieldConfig); + } + return fieldConfig; + }, + [MapperKind.INTERFACE_TYPE]: interfaceConfig => { + const testDirectiveConfig = getDirective(schema, interfaceConfig, testDirective.name)?.[0]; + if (testDirectiveConfig) { + const config = interfaceConfig.toConfig(); + return new GraphQLInterfaceType(mapConfig(config)); + } + return interfaceConfig; + }, + [MapperKind.INTERFACE_FIELD]: fieldConfig => { + const testDirectiveConfig = getDirective(schema, fieldConfig, testDirective.name)?.[0]; + if (testDirectiveConfig) { + return mapConfig(fieldConfig); + } + return fieldConfig; + }, + [MapperKind.INPUT_OBJECT_TYPE]: typeInfo => { + const testDirectiveConfig = getDirective(schema, typeInfo, testDirective.name)?.[0]; + if (testDirectiveConfig) { + const config = typeInfo.toConfig(); + return new GraphQLInputObjectType(mapConfig(config)); + } + return typeInfo; + }, + [MapperKind.INPUT_OBJECT_FIELD]: fieldConfig => { + const testDirectiveConfig = getDirective(schema, fieldConfig, testDirective.name)?.[0]; + if (testDirectiveConfig) { + return mapConfig(fieldConfig); + } + return fieldConfig; + }, + [MapperKind.ARGUMENT]: argumentConfig => { + const testDirectiveConfig = getDirective(schema, argumentConfig, testDirective.name)?.[0]; + if (testDirectiveConfig) { + return mapConfig(argumentConfig); + } + return argumentConfig; + }, + }); +} diff --git a/tests/helpers/directives/UpperCaseDirective.ts b/tests/helpers/directives/UpperCaseDirective.ts deleted file mode 100644 index 9c8979b92..000000000 --- a/tests/helpers/directives/UpperCaseDirective.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { - GraphQLField, - GraphQLDirective, - DirectiveLocation, - GraphQLInputObjectType, - GraphQLInputField, - GraphQLScalarType, - GraphQLNonNull, -} from "graphql"; -import { SchemaDirectiveVisitor } from "graphql-tools"; - -class UpperCaseType extends GraphQLScalarType { - constructor(type: any) { - super({ - name: "UpperCase", - parseValue: value => this.upper(type.parseValue(value)), - serialize: value => this.upper(type.serialize(value)), - parseLiteral: ast => this.upper(type.parseLiteral(ast)), - }); - } - - upper(value: any) { - return typeof value === "string" ? value.toUpperCase() : value; - } -} - -export class UpperCaseDirective extends SchemaDirectiveVisitor { - static getDirectiveDeclaration(directiveName: string): GraphQLDirective { - return new GraphQLDirective({ - name: directiveName, - locations: [DirectiveLocation.FIELD_DEFINITION], - }); - } - - visitFieldDefinition(field: GraphQLField) { - this.wrapField(field); - } - - visitInputObject(object: GraphQLInputObjectType) { - const fields = object.getFields(); - - Object.keys(fields).forEach(field => { - this.wrapField(fields[field]); - }); - } - - visitInputFieldDefinition(field: GraphQLInputField) { - this.wrapField(field); - } - - wrapField(field: GraphQLField | GraphQLInputField): void { - if (field.type instanceof UpperCaseType) { - /* noop */ - } else if ( - field.type instanceof GraphQLNonNull && - field.type.ofType instanceof GraphQLScalarType - ) { - field.type = new GraphQLNonNull(new UpperCaseType(field.type.ofType)); - } else if (field.type instanceof GraphQLScalarType) { - field.type = new UpperCaseType(field.type); - } else { - throw new Error(`Not a scalar type: ${field.type}`); - } - } -} diff --git a/tests/helpers/directives/assertValidDirective.ts b/tests/helpers/directives/assertValidDirective.ts index 49025debf..1fb87ab93 100644 --- a/tests/helpers/directives/assertValidDirective.ts +++ b/tests/helpers/directives/assertValidDirective.ts @@ -1,22 +1,23 @@ import { - FieldDefinitionNode, - InputObjectTypeDefinitionNode, - InputValueDefinitionNode, - InterfaceTypeDefinitionNode, + type FieldDefinitionNode, + type InputObjectTypeDefinitionNode, + type InputValueDefinitionNode, + type InterfaceTypeDefinitionNode, + type ObjectTypeDefinitionNode, parseValue, } from "graphql"; - -import { Maybe } from "../../../src/interfaces/Maybe"; +import { type Maybe } from "@/typings"; export function assertValidDirective( astNode: Maybe< | FieldDefinitionNode + | ObjectTypeDefinitionNode | InputObjectTypeDefinitionNode | InputValueDefinitionNode | InterfaceTypeDefinitionNode >, name: string, - args?: { [key: string]: string }, + args?: Record, ): void { if (!astNode) { throw new Error(`Directive with name ${name} does not exist`); @@ -37,12 +38,17 @@ export function assertValidDirective( expect(directive.arguments).toBeFalsy(); } } else { + expect(directive.arguments).toHaveLength(Object.keys(args).length); expect(directive.arguments).toEqual( - Object.keys(args).map(arg => ({ - kind: "Argument", - name: { kind: "Name", value: arg }, - value: parseValue(args[arg]), - })), + expect.arrayContaining( + Object.keys(args).map(arg => + expect.objectContaining({ + kind: "Argument", + name: expect.objectContaining({ kind: "Name", value: arg }), + value: expect.objectContaining(parseValue(args[arg], { noLocation: true })), + }), + ), + ), ); } } diff --git a/tests/helpers/expectToThrow.ts b/tests/helpers/expectToThrow.ts new file mode 100644 index 000000000..e4582930d --- /dev/null +++ b/tests/helpers/expectToThrow.ts @@ -0,0 +1,9 @@ +export async function expectToThrow(call: () => unknown): Promise { + try { + await call(); + } catch (error: unknown) { + return error as TError; + } + + throw new Error("You've expected a function to throw, but it didn't throw anything."); +} diff --git a/tests/helpers/getInnerFieldType.ts b/tests/helpers/getInnerFieldType.ts index ae87eb5bd..80e2a12a3 100644 --- a/tests/helpers/getInnerFieldType.ts +++ b/tests/helpers/getInnerFieldType.ts @@ -1,15 +1,16 @@ import { - IntrospectionObjectType, - IntrospectionInterfaceType, - IntrospectionNonNullTypeRef, - IntrospectionNamedTypeRef, - IntrospectionInputObjectType, - IntrospectionTypeRef, - IntrospectionEnumType, - IntrospectionScalarType, - IntrospectionUnionType, + type IntrospectionInputObjectType, + type IntrospectionInterfaceType, + type IntrospectionNamedTypeRef, + type IntrospectionNonNullTypeRef, + type IntrospectionObjectType, + type IntrospectionTypeRef, } from "graphql"; +export function getInnerTypeOfNonNullableType(definition: { type: IntrospectionTypeRef }) { + return (definition.type as IntrospectionNonNullTypeRef).ofType! as IntrospectionNamedTypeRef; +} + export function getInnerFieldType( type: IntrospectionObjectType | IntrospectionInterfaceType, name: string, @@ -21,10 +22,6 @@ export function getInnerInputFieldType(type: IntrospectionInputObjectType, name: return getInnerTypeOfNonNullableType(type.inputFields.find(field => field.name === name)!); } -export function getInnerTypeOfNonNullableType(definition: { type: IntrospectionTypeRef }) { - return (definition.type as IntrospectionNonNullTypeRef).ofType! as IntrospectionNamedTypeRef; -} - export function getItemTypeOfList(definition: { type: IntrospectionTypeRef }) { const listType = (definition.type as IntrospectionNonNullTypeRef) .ofType! as IntrospectionNonNullTypeRef; diff --git a/tests/helpers/getSampleObjectFieldType.ts b/tests/helpers/getSampleObjectFieldType.ts index 4b327c215..999b843c8 100644 --- a/tests/helpers/getSampleObjectFieldType.ts +++ b/tests/helpers/getSampleObjectFieldType.ts @@ -1,8 +1,8 @@ import { - IntrospectionNamedTypeRef, - IntrospectionObjectType, - IntrospectionNonNullTypeRef, - IntrospectionSchema, + type IntrospectionNamedTypeRef, + type IntrospectionNonNullTypeRef, + type IntrospectionObjectType, + type IntrospectionSchema, } from "graphql"; export function getSampleObjectFieldType(schemaIntrospection: IntrospectionSchema) { diff --git a/tests/helpers/getSchemaInfo.ts b/tests/helpers/getSchemaInfo.ts index 6a458cd6d..43eded1d8 100644 --- a/tests/helpers/getSchemaInfo.ts +++ b/tests/helpers/getSchemaInfo.ts @@ -1,22 +1,27 @@ +/* eslint "no-underscore-dangle": ["error", { "allow": ["__schema"] }] */ import { - graphql, + type IntrospectionObjectType, + type IntrospectionSchema, getIntrospectionQuery, - IntrospectionObjectType, - IntrospectionSchema, + graphql, } from "graphql"; - -import { buildSchema, BuildSchemaOptions } from "../../src"; +import { type BuildSchemaOptions, buildSchema } from "type-graphql"; export async function getSchemaInfo(options: BuildSchemaOptions) { - // build schema from definitions + // Build schema from definitions const schema = await buildSchema({ ...options, validate: false, skipCheck: true, }); - // get builded schema info from retrospection - const result = await graphql(schema, getIntrospectionQuery()); + // Get built schema info from retrospection + const result = await graphql({ + schema, + source: getIntrospectionQuery({ + inputValueDeprecation: true, + }), + }); expect(result.errors).toBeUndefined(); const schemaIntrospection = result.data!.__schema as IntrospectionSchema; diff --git a/tests/helpers/getTypeField.ts b/tests/helpers/getTypeField.ts index 669577237..17aaa9d76 100644 --- a/tests/helpers/getTypeField.ts +++ b/tests/helpers/getTypeField.ts @@ -1,4 +1,8 @@ -import { IntrospectionField, IntrospectionObjectType, IntrospectionInterfaceType } from "graphql"; +import { + type IntrospectionField, + type IntrospectionInterfaceType, + type IntrospectionObjectType, +} from "graphql"; export function getTypeField( type: IntrospectionObjectType | IntrospectionInterfaceType, diff --git a/tests/helpers/loading-from-directories/sample.resolver.ts b/tests/helpers/loading-from-directories/sample.resolver.ts deleted file mode 100644 index 125d75445..000000000 --- a/tests/helpers/loading-from-directories/sample.resolver.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Query } from "../../../src"; - -import { SampleObject } from "./sample.type"; - -export class Resolver { - @Query() - sampleQuery(): SampleObject { - return { - sampleField: "sampleField", - }; - } -} diff --git a/tests/helpers/loading-from-directories/sample.type.ts b/tests/helpers/loading-from-directories/sample.type.ts deleted file mode 100644 index 47d4e73ff..000000000 --- a/tests/helpers/loading-from-directories/sample.type.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Field, ObjectType } from "../../../src"; - -@ObjectType() -export class SampleObject { - @Field() - sampleField: string; -} diff --git a/tests/helpers/sleep.ts b/tests/helpers/sleep.ts index 92793a163..c51596d8a 100644 --- a/tests/helpers/sleep.ts +++ b/tests/helpers/sleep.ts @@ -1,3 +1,5 @@ -export default function sleep(ms: number) { - return new Promise(resolve => setTimeout(resolve, ms)); +export function sleep(ms: number): Promise { + return new Promise(resolve => { + setTimeout(resolve, ms); + }); } diff --git a/tests/tsconfig.json b/tests/tsconfig.json new file mode 100644 index 000000000..35a3dcbf3 --- /dev/null +++ b/tests/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "noEmit": true, + "noUnusedLocals": false, + "emitDecoratorMetadata": true + }, + "include": [".", "../src"] +} diff --git a/tsconfig.cjs.json b/tsconfig.cjs.json new file mode 100644 index 000000000..f5f4bd1aa --- /dev/null +++ b/tsconfig.cjs.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "commonjs", + "outDir": "./build/cjs" + } +} diff --git a/tsconfig.esm.json b/tsconfig.esm.json new file mode 100644 index 000000000..740a7914a --- /dev/null +++ b/tsconfig.esm.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "es2020", + "moduleResolution": "bundler", + "outDir": "./build/esm" + } +} diff --git a/tsconfig.json b/tsconfig.json index d59283ce0..b123f8c01 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,69 +1,50 @@ { "compilerOptions": { - /* Basic Options */ - "target": "es2018", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "lib": [ /* Specify library files to be included in the compilation. */ - "es2018", - "esnext.asynciterable" - ], - // "allowJs": true, /* Allow javascript files to be compiled. */ - // "checkJs": true, /* Report errors in .js files. */ - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - "outDir": "./build", /* Redirect output structure to the directory. */ - // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ - "removeComments": false, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ - // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - - /* Strict Type-Checking Options */ - "strict": false, /* Enable all strict type-checking options. */ - "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - "strictNullChecks": true, /* Enable strict null checks. */ - "strictFunctionTypes": true, /* Enable strict checking of function types. */ - "strictPropertyInitialization": false, /* Enable strict checking of property initialization in classes. */ - "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - - /* Additional Checks */ - "noUnusedLocals": false, /* Report errors on unused locals. */ - "noUnusedParameters": false, /* Report errors on unused parameters. */ - "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - - /* Module Resolution Options */ - "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - // "types": [], /* Type declaration files to be included in compilation. */ - "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + "target": "es2021", + "module": "commonjs", + "declaration": false, + "sourceMap": false, + "outDir": "./build", + "moduleResolution": "node", + "removeComments": true, + "importHelpers": true, + "strict": true, + "allowUnreachableCode": false, + "allowUnusedLabels": false, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitOverride": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, "forceConsistentCasingInFileNames": true, - "skipLibCheck": true, /* Don't check libs typings - due to https://github.com/prisma/graphql-request/issues/26 */ - - /* Source Map Options */ - // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */ + "skipLibCheck": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": false, + "resolveJsonModule": true, + "plugins": [ + { + "transform": "typescript-transform-paths" + }, + { + "transform": "typescript-transform-paths", + "afterDeclarations": true + }, + { + "transform": "typescript-transformer-esm", + "after": true + }, + { + "transform": "typescript-transformer-esm", + "afterDeclarations": true + } + ], + "paths": { + "@/*": ["./src/*"], + "type-graphql": ["./src/index.ts"] + } }, - "include": [ - "./src", - "./tests" - ], - "exclude": [ - "./examples/apollo-client" - ] + "exclude": ["./node_modules", "./build"], + "include": ["./src"] } diff --git a/tsconfig.package.json b/tsconfig.package.json deleted file mode 100644 index 857937154..000000000 --- a/tsconfig.package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["./src"] -} diff --git a/tsconfig.typings.json b/tsconfig.typings.json new file mode 100644 index 000000000..aa8b53d76 --- /dev/null +++ b/tsconfig.typings.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./build/typings", + "emitDeclarationOnly": true, + "declaration": true, + "removeComments": false + } +} diff --git a/tslint.json b/tslint.json deleted file mode 100644 index ad85c31e8..000000000 --- a/tslint.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": ["tslint:recommended", "tslint-eslint-rules", "tslint-config-prettier"], - "rules": { - "adjacent-overload-signatures": true, - "ban-types": false, - "no-console": [false], - "no-namespace": false, - "object-literal-sort-keys": false, - "max-classes-per-file": false, - "member-access": [true, "no-public"], - "member-ordering": [ - true, - { - "order": [ - "public-static-field", - "protected-static-field", - "private-static-field", - - "public-instance-field", - "protected-instance-field", - "private-instance-field", - - "public-static-method", - "protected-static-method", - "private-static-method", - - "public-constructor", - "protected-constructor", - "private-constructor", - - "public-instance-method", - "protected-instance-method", - "private-instance-method" - ] - } - ], - "unified-signatures": false, - "interface-name": [true, "never-prefix"], - "ordered-imports": false, - "no-unused-expression": false, - "callable-types": false, - "variable-name": [ - true, - "ban-keywords", - "check-format", - "allow-leading-underscore", - "allow-pascal-case" - ], - "array-type": [true, "array-simple"] - } -} diff --git a/website/blog/2018-03-25-medium-article.md b/website/blog/2018-03-25-medium-article.md index 76b752b3b..66cb68c30 100644 --- a/website/blog/2018-03-25-medium-article.md +++ b/website/blog/2018-03-25-medium-article.md @@ -14,27 +14,32 @@ We all love GraphQL! It’s so great and solves many problems that we have with ![type-graphql-logo](/blog/assets/logo_mini.png) ## Motivation + As I mentioned, developing a GraphQL API in Node.js with TypeScript might be a painful process. Why? Let’s take a look at the steps we usually have to make. At first, we create the all the schema types in SDL. We also create our data models using ORM classes, which represents our db entities. Then we start to write resolvers for our queries, mutations and fields but this force us to begin with creating TS interfaces for all arguments and inputs or even object types. And after that we can actually implements the resolvers, using weird generic signatures, e.g.: ```typescript -export const recipesResolver: GraphQLFieldResolver = - async (_, args) => { - // stuffs like validation, auth checking, getting from container - // and our business logic, e.g.: - const repository = getRepository(Recipe); - return repository.find(); - } +export const recipesResolver: GraphQLFieldResolver = async ( + _, + args, +) => { + // stuffs like validation, auth checking, getting from container + // and our business logic, e.g.: + const repository = getRepository(Recipe); + return repository.find(); +}; ``` + The biggest problem is the rendundancy in our codebase, that makes difficult to keep this things in sync. To add new field to our entity, we have to jump through all the filesβ€Šβ€”β€Šmodify entity class, then modify part of the schema and then update the interface. The same goes with inputs or arguments, it’s easy to forget to update one or make a mistake with the type. Also, what if we’ve made a typo in field name? The rename feature (F2) won’t work correctly. **TypeGraphQL** comes to address this issues, based on experience from over a dozen months of developing GraphQL APIs in TypeScript. The main idea is to have only one source of truth by defining the schema using classes and a bit of decorators help. Additional features like dependency injection, validation or auth guards helps with common task that normally we would have to handle by ourselves. ## Getting started + To explore all powerful capabilities of TypeGraphQL, we will create a sample GraphQL API for cooking recipes. -Let’s start with the Recipe type, which is the foundations of our API. +Let’s start with the Recipe type, which is the foundations of our API. We want to get equivalent of this type described in SDL: ```graphql @@ -48,6 +53,7 @@ type Recipe { ``` So we create the Recipe class with all properties and types: + ```typescript class Recipe { id: string; @@ -59,6 +65,7 @@ class Recipe { ``` Then we annotate the class and it properties with decorators: + ```typescript @ObjectType() class Recipe { @@ -82,7 +89,9 @@ class Recipe { The detailed rules when to use `nullable`, `array` and other options are described in [fields and types docs](https://github.com/MichalLytek/type-graphql/blob/master/docs/types-and-fields.md). ### Resolvers + After that we want to create typical crud queries and mutation. To do that we create the resolver (controller) class that will have injected RecipeService in constructor: + ```typescript @Resolver(Recipe) class RecipeResolver { @@ -127,7 +136,9 @@ class RecipeResolver { We use `@Authorized()` decorator to restrict access only for authorized users or the one that fulfill the roles requirements. The detailed rules when and why we declare `returns => Recipe` functions and others are described in [resolvers docs](https://github.com/MichalLytek/type-graphql/blob/master/docs/resolvers.md). ### Inputs and arguments + Ok, but what are theNewRecipeInput and RecipesArgs? There are of course classes that declares input type and arguments: + ```typescript @InputType() class NewRecipeDataInput { @@ -151,25 +162,28 @@ class RecipesArgs { skip: number = 0; @Field(type => Int, { nullable: true }) - @Min(1) @Max(50) + @Min(1) + @Max(50) take: number = 25; } ``` `@Length`, `@Min` or `@MaxArraySize` are decorators from [`class-validator`](https://github.com/typestack/class-validator) that automatically perform fields validation in TypeGraphQL. - ### Building schema + The last step that we have to do is to actually build the schema from TypeGraphQL definition. We use buildSchema function for this: + ```typescript const schema = await buildSchema({ - resolvers: [RecipeResolver] + resolvers: [RecipeResolver], }); // ...creating express server or sth ``` Et voilΓ ! Now we have fully working GraphQL schema! If we print it, we would receive exactly this: + ```graphql type Recipe { id: ID! @@ -194,16 +208,19 @@ type Mutation { ``` ## Want more? + That was only a tip of the icebergβ€Šβ€”β€Ša very simple example with basic GraphQL types. Do you use interfaces, enums, unions and custom scalars? That’s great because TypeGraphQL fully supports them too! If you want to see how it looks in more complicated case, you can go to the [Examples section](https://github.com/MichalLytek/type-graphql/blob/master/examples) where you can find how nice TypeGraphQL integrates with TypeORM. Want to learn about more advanced concepts like authorization checker, inheritance support or field resolvers? Check out the [Docs section](https://github.com/MichalLytek/type-graphql/blob/master/docs). ## Work in progress + Currently released version is a **MVP** (Minimum Viable Product). It is well tested (95% coverage, 4400 lines of test code) and has 90% of the planned features already implemented. However there’s some work to be done before 1.0.0 release and it’s mostly about documentation (website, api reference and jsdoc). There are also plans for more features like better TypeORM and dataloader integration or middlewares and custom decorators supportβ€Šβ€”β€Š[the full list of ideas](https://github.com/MichalLytek/type-graphql/issues?q=is%3Aissue+is%3Aopen+label%3A%22Enhancement+%3Anew%3A%22) is available on the GitHub repo. You can also keep track of [development’s progress on project board](https://github.com/MichalLytek/type-graphql/projects/1). ## Spread the word + I strongly encourage you to give it a try and experiment with **TypeGraphQL**. I promise, it will reduce your codebase by a half or more! diff --git a/website/blog/2020-08-19-devto-article.md b/website/blog/2020-08-19-devto-article.md index a3dac4020..451949528 100644 --- a/website/blog/2020-08-19-devto-article.md +++ b/website/blog/2020-08-19-devto-article.md @@ -25,25 +25,25 @@ This post is focused mostly on presenting new features and describing changes in One of the most important things which is also often neglected by developers - the performance. One of the key focus area for the 1.0 release was making it blazingly fast ⚑ -TypeGraphQL is basically an abstraction layer built on top of the reference GraphQL implementation for JavaScript - `graphql-js`. To measure the overhead of the abstraction, a few demo examples were made to compare it against the "bare metal" - using raw `graphql-js` library. +TypeGraphQL is basically an abstraction layer built on top of the reference GraphQL implementation for JavaScript - `graphql-js`. To measure the overhead of the abstraction, a few demo examples were made to compare it against the "bare metal" - using raw `graphql-js` library. It turned out that in the most demanding cases like returning an array of 25 000 nested objects, the old version `0.17` was even about 5 times slower! -| library | execution time | -| -------------------- | :------------: | -| TypeGraphQL `v0.17` | 1253.28 ms | -| `graphql-js` | 265.52 ms | +| library | execution time | +| ------------------- | :------------: | +| TypeGraphQL `v0.17` | 1253.28 ms | +| `graphql-js` | 265.52 ms | After profiling the code and finding all the root causes (like always using async execution path), the overhead was reduced from 500% to **just 17%** in `v1.0.0`! By using [`simpleResolvers`](https://typegraphql.com/docs/performance.html#further-performance-tweaks) it can be reduced even further, up to 13%: | | execution time | | ------------------------ | :------------: | -| `graphql-js` | 265.52 ms | -| **TypeGraphQL `v1.0`** | 310.36 ms | -| with "simpleResolvers" | 299.61 ms | +| `graphql-js` | 265.52 ms | +| **TypeGraphQL `v1.0`** | 310.36 ms | +| with "simpleResolvers" | 299.61 ms | | with a global middleware | 1267.82 ms | -Such small overhead is much easier to accept than the initial 500%! +Such small overhead is much easier to accept than the initial 500%! More info about how to enable the performance optimizations in the more complex cases can be found [in the docs πŸ“–](https://typegraphql.com/docs/performance.html). ## Schema isolation @@ -53,7 +53,7 @@ This is another feature that is not visible from the first sight but gives new p In 0.17.x and before, the schema was built from all the metadata collected by evaluating the TypeGraphQL decorators. The drawback of this approach was the schema leaks - every subsequent calls of `buildSchema` was returning the same schema which was combined from all the types and resolvers that could be find in the metadata storage. In TypeGraphQL 1.0 it's no longer true! -The schemas are now isolated which means that the [`buildSchema` call takes the `resolvers` array from options](https://typegraphql.com/docs/bootstrap.html#create-executable-schema) and emit only the queries, mutation and types that are related to those resolvers. +The schemas are now isolated which means that the [`buildSchema` call takes the `resolvers` array from options](https://typegraphql.com/docs/bootstrap.html#create-executable-schema) and emit only the queries, mutation and types that are related to those resolvers. ```ts const firstSchema = await buildSchema({ @@ -75,7 +75,7 @@ GraphQL directives though the syntax might remind the TS decorators, as "a direc ```graphql type Query { - foobar: String! @auth(requires: USER) + foobar: String! @auth(requires: USER) } ``` @@ -91,6 +91,7 @@ class FooBarResolver { } } ``` + However, on the other side we have the GraphQL extensions which are the JS way to achieve the same goal. It's the recommended way of putting the metadata about the types when applying some custom logic. To declare the extensions for type or selected field, we need to use `@Extensions` decorator, e.g.: @@ -136,17 +137,20 @@ abstract class IPerson { ## More descriptive errors messages -One of the most irritating issues for newcomers were the laconic error messages that haven't provided enough info to easily find the mistakes in the code. +One of the most irritating issues for newcomers were the laconic error messages that haven't provided enough info to easily find the mistakes in the code. Messages like _"Cannot determine GraphQL input type for users"_ or even the a generic _"Generating schema error"_ were clearly not helpful enough while searching for the place where the flaws were located. Now, when the error occurs, it is broadly explained, why it happened and what could we do to fix that, e.g.: + ```text Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for argument named 'filter' of 'getUsers' of 'UserResolver' class. ``` + or: + ```text Some errors occurred while generating GraphQL schema: Interface field 'IUser.accountBalance' expects type 'String!' @@ -157,7 +161,7 @@ That should allow developers to safe tons of time and really speed up the develo ## Transforming nested inputs and arrays -In the previous releases, an instance of the input type class was created only on the first level of inputs nesting. +In the previous releases, an instance of the input type class was created only on the first level of inputs nesting. So, in cases like this: ```ts @@ -179,7 +183,7 @@ class SampleResolver { } ``` -the `nestedField` property of `input` was just a plain `Object`, not an instance of the `SomeNestedInput` class. That behavior was producing some unwanted issues, including limited support for [inputs and args validation](https://typegraphql.com/docs/validation.html). +the `nestedField` property of `input` was just a plain `Object`, not an instance of the `SomeNestedInput` class. That behavior was producing some unwanted issues, including limited support for [inputs and args validation](https://typegraphql.com/docs/validation.html). Since 1.0 release, it's no longer an issue and all the nested args and inputs are properly transformed to the corresponding input type classes instances, even including deeply nested arrays πŸ’ͺ diff --git a/website/i18n/en.json b/website/i18n/en.json index a50430806..3af42bae0 100644 --- a/website/i18n/en.json +++ b/website/i18n/en.json @@ -8,6 +8,9 @@ "authorization": { "title": "Authorization" }, + "aws-lambda": { + "title": "AWS Lambda integration" + }, "bootstrap": { "title": "Bootstrapping" }, @@ -32,6 +35,9 @@ "enums": { "title": "Enums" }, + "esm": { + "title": "ECMAScript Modules" + }, "examples": { "title": "Examples", "sidebar_label": "List of examples" @@ -64,6 +70,10 @@ "middlewares": { "title": "Middleware and guards" }, + "migration-guide": { + "title": "Migration Guide", + "sidebar_label": "v1.x -> v2.0" + }, "nestjs": { "title": "NestJS Integration", "sidebar_label": "NestJS" @@ -72,8 +82,8 @@ "title": "Performance" }, "prisma": { - "title": "Prisma 2 Integration", - "sidebar_label": "Prisma 2" + "title": "Prisma Integration", + "sidebar_label": "Prisma" }, "README": { "title": "README" @@ -425,8 +435,8 @@ "title": "Performance" }, "version-1.0.0/version-1.0.0-prisma": { - "title": "Prisma 2 Integration", - "sidebar_label": "Prisma 2" + "title": "Prisma Integration", + "sidebar_label": "Prisma" }, "version-1.0.0/version-1.0.0-resolvers": { "title": "Resolvers" @@ -454,10 +464,6 @@ "title": "Examples", "sidebar_label": "List of examples" }, - "version-1.1.0/version-1.1.0-prisma": { - "title": "Prisma 2 Integration", - "sidebar_label": "Prisma 2" - }, "version-1.1.0/version-1.1.0-validation": { "title": "Argument and Input validation", "sidebar_label": "Validation" @@ -552,6 +558,205 @@ "version-1.2.0-rc.1/version-1.2.0-rc.1-validation": { "title": "Argument and Input validation", "sidebar_label": "Validation" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-authorization": { + "title": "Authorization" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-bootstrap": { + "title": "Bootstrapping" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-browser-usage": { + "title": "Browser usage" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-complexity": { + "title": "Query complexity" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-custom-decorators": { + "title": "Custom decorators" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-dependency-injection": { + "title": "Dependency injection" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-directives": { + "title": "Directives" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-emit-schema": { + "title": "Emitting the schema SDL" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-enums": { + "title": "Enums" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-esm": { + "title": "ECMAScript Modules" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-examples": { + "title": "Examples", + "sidebar_label": "List of examples" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-extensions": { + "title": "Extensions" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-faq": { + "title": "Frequently Asked Questions" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-generic-types": { + "title": "Generic Types" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-getting-started": { + "title": "Getting started" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-inheritance": { + "title": "Inheritance" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-installation": { + "title": "Installation" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-interfaces": { + "title": "Interfaces" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-introduction": { + "title": "Introduction", + "sidebar_label": "What & Why" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-middlewares": { + "title": "Middleware and guards" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-nestjs": { + "title": "NestJS Integration", + "sidebar_label": "NestJS" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-performance": { + "title": "Performance" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-prisma": { + "title": "Prisma Integration", + "sidebar_label": "Prisma" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-resolvers": { + "title": "Resolvers" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-scalars": { + "title": "Scalars" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-subscriptions": { + "title": "Subscriptions" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-types-and-fields": { + "title": "Types and Fields" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-unions": { + "title": "Unions" + }, + "version-2.0.0-beta.3/version-2.0.0-beta.3-validation": { + "title": "Argument and Input validation", + "sidebar_label": "Validation" + }, + "version-2.0.0-beta.4/version-2.0.0-beta.4-authorization": { + "title": "Authorization" + }, + "version-2.0.0-beta.4/version-2.0.0-beta.4-aws-lambda": { + "title": "AWS Lambda integration" + }, + "version-2.0.0-beta.4/version-2.0.0-beta.4-browser-usage": { + "title": "Browser usage" + }, + "version-2.0.0-beta.4/version-2.0.0-beta.4-complexity": { + "title": "Query complexity" + }, + "version-2.0.0-beta.4/version-2.0.0-beta.4-custom-decorators": { + "title": "Custom decorators" + }, + "version-2.0.0-beta.4/version-2.0.0-beta.4-dependency-injection": { + "title": "Dependency injection" + }, + "version-2.0.0-beta.4/version-2.0.0-beta.4-directives": { + "title": "Directives" + }, + "version-2.0.0-beta.4/version-2.0.0-beta.4-emit-schema": { + "title": "Emitting the schema SDL" + }, + "version-2.0.0-beta.4/version-2.0.0-beta.4-esm": { + "title": "ECMAScript Modules" + }, + "version-2.0.0-beta.4/version-2.0.0-beta.4-examples": { + "title": "Examples", + "sidebar_label": "List of examples" + }, + "version-2.0.0-beta.4/version-2.0.0-beta.4-extensions": { + "title": "Extensions" + }, + "version-2.0.0-beta.4/version-2.0.0-beta.4-generic-types": { + "title": "Generic Types" + }, + "version-2.0.0-beta.4/version-2.0.0-beta.4-inheritance": { + "title": "Inheritance" + }, + "version-2.0.0-beta.4/version-2.0.0-beta.4-interfaces": { + "title": "Interfaces" + }, + "version-2.0.0-beta.4/version-2.0.0-beta.4-middlewares": { + "title": "Middleware and guards" + }, + "version-2.0.0-beta.4/version-2.0.0-beta.4-migration-guide": { + "title": "Migration Guide", + "sidebar_label": "v1.x -> v2.0" + }, + "version-2.0.0-beta.4/version-2.0.0-beta.4-resolvers": { + "title": "Resolvers" + }, + "version-2.0.0-beta.4/version-2.0.0-beta.4-subscriptions": { + "title": "Subscriptions" + }, + "version-2.0.0-beta.4/version-2.0.0-beta.4-unions": { + "title": "Unions" + }, + "version-2.0.0-beta.4/version-2.0.0-beta.4-validation": { + "title": "Argument and Input validation", + "sidebar_label": "Validation" + }, + "version-2.0.0-beta.6/version-2.0.0-beta.6-authorization": { + "title": "Authorization" + }, + "version-2.0.0-beta.6/version-2.0.0-beta.6-complexity": { + "title": "Query complexity" + }, + "version-2.0.0-beta.6/version-2.0.0-beta.6-custom-decorators": { + "title": "Custom decorators" + }, + "version-2.0.0-beta.6/version-2.0.0-beta.6-dependency-injection": { + "title": "Dependency injection" + }, + "version-2.0.0-beta.6/version-2.0.0-beta.6-examples": { + "title": "Examples", + "sidebar_label": "List of examples" + }, + "version-2.0.0-beta.6/version-2.0.0-beta.6-extensions": { + "title": "Extensions" + }, + "version-2.0.0-beta.6/version-2.0.0-beta.6-generic-types": { + "title": "Generic Types" + }, + "version-2.0.0-beta.6/version-2.0.0-beta.6-inheritance": { + "title": "Inheritance" + }, + "version-2.0.0-beta.6/version-2.0.0-beta.6-interfaces": { + "title": "Interfaces" + }, + "version-2.0.0-beta.6/version-2.0.0-beta.6-middlewares": { + "title": "Middleware and guards" + }, + "version-2.0.0-beta.6/version-2.0.0-beta.6-resolvers": { + "title": "Resolvers" + }, + "version-2.0.0-beta.6/version-2.0.0-beta.6-subscriptions": { + "title": "Subscriptions" + }, + "version-2.0.0-beta.6/version-2.0.0-beta.6-unions": { + "title": "Unions" + }, + "version-2.0.0-beta.6/version-2.0.0-beta.6-validation": { + "title": "Argument and Input validation", + "sidebar_label": "Validation" } }, "links": { @@ -565,10 +770,12 @@ "categories": { "Introduction": "Introduction", "Beginner guides": "Beginner guides", + "Migration guide": "Migration guide", "Advanced guides": "Advanced guides", "Features": "Features", "Integrations": "Integrations", "Others": "Others", + "Recipes": "Recipes", "Examples": "Examples" } }, diff --git a/website/package-lock.json b/website/package-lock.json index 1d2886942..a597d1a7b 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -1,1557 +1,2443 @@ { + "name": "website", + "lockfileVersion": 3, "requires": true, - "lockfileVersion": 1, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "packages": { + "": { + "devDependencies": { + "docusaurus": "^1.14.7" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" + "dependencies": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" } }, - "@babel/compat-data": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.11.0.tgz", - "integrity": "sha512-TPSvJfv73ng0pfnEOh17bYMPQbI95+nGWc71Ss4vZdRBHTDqmM9Z8ZV4rYz8Ks7sfzc95n30k6ODIq5UGnXcYQ==", + "node_modules/@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", "dev": true, - "requires": { - "browserslist": "^4.12.0", - "invariant": "^2.2.4", - "semver": "^5.5.0" - } - }, - "@babel/core": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.1.tgz", - "integrity": "sha512-XqF7F6FWQdKGGWAzGELL+aCO1p+lRY5Tj5/tbT3St1G8NaH70jhhDIKknIZaDans0OQBG5wRAldROLHSt44BgQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.11.0", - "@babel/helper-module-transforms": "^7.11.0", - "@babel/helpers": "^7.10.4", - "@babel/parser": "^7.11.1", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.11.0", - "@babel/types": "^7.11.0", + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.20.14", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.14.tgz", + "integrity": "sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.20.12", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", + "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helpers": "^7.20.7", + "@babel/parser": "^7.20.7", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.12", + "@babel/types": "^7.20.7", "convert-source-map": "^1.7.0", "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.19", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, - "@babel/generator": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.0.tgz", - "integrity": "sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ==", + "node_modules/@babel/generator": { + "version": "7.20.14", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.14.tgz", + "integrity": "sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==", "dev": true, - "requires": { - "@babel/types": "^7.11.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" + "dependencies": { + "@babel/types": "^7.20.7", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-annotate-as-pure": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz", - "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==", + "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==", "dev": true, - "requires": { - "@babel/types": "^7.10.4" + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" } }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz", - "integrity": "sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg==", + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", + "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", "dev": true, - "requires": { - "@babel/helper-explode-assignable-expression": "^7.10.4", - "@babel/types": "^7.10.4" + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-builder-react-jsx": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.4.tgz", - "integrity": "sha512-5nPcIZ7+KKDxT1427oBivl9V9YTal7qk0diccnh7RrcgrT/pGFOjgGw1dgryyx1GvHEpXVfoDF6Ak3rTiWh8Rg==", + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", + "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/types": "^7.10.4" + "dependencies": { + "@babel/helper-explode-assignable-expression": "^7.18.6", + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-builder-react-jsx-experimental": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.10.5.tgz", - "integrity": "sha512-Buewnx6M4ttG+NLkKyt7baQn7ScC/Td+e99G914fRU8fGIUivDDgVIQeDHFa5e4CRSJQt58WpNHhsAZgtzVhsg==", + "node_modules/@babel/helper-compilation-targets": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-module-imports": "^7.10.4", - "@babel/types": "^7.10.5" + "dependencies": { + "@babel/compat-data": "^7.20.5", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/helper-compilation-targets": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.4.tgz", - "integrity": "sha512-a3rYhlsGV0UHNDvrtOXBg8/OpfV0OKTkxKPzIplS1zpx7CygDcWWxckxZeDd3gzPzC4kUT0A4nVFDK0wGMh4MQ==", + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.20.12", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz", + "integrity": "sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==", "dev": true, - "requires": { - "@babel/compat-data": "^7.10.4", - "browserslist": "^4.12.0", - "invariant": "^2.2.4", - "levenary": "^1.1.1", - "semver": "^5.5.0" + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-member-expression-to-functions": "^7.20.7", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-replace-supers": "^7.20.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/helper-split-export-declaration": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/helper-create-class-features-plugin": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.5.tgz", - "integrity": "sha512-0nkdeijB7VlZoLT3r/mY3bUkw3T8WG/hNw+FATs/6+pG2039IJWjTYL0VTISqsNHMUTEnwbVnc89WIJX9Qed0A==", + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz", + "integrity": "sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==", "dev": true, - "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-member-expression-to-functions": "^7.10.5", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.10.4" + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "regexpu-core": "^5.2.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz", - "integrity": "sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g==", + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", + "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-regex": "^7.10.4", - "regexpu-core": "^4.7.0" + "dependencies": { + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-plugin-utils": "^7.16.7", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0-0" } }, - "@babel/helper-define-map": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz", - "integrity": "sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ==", + "node_modules/@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", "dev": true, - "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/types": "^7.10.5", - "lodash": "^4.17.19" + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-explode-assignable-expression": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.4.tgz", - "integrity": "sha512-4K71RyRQNPRrR85sr5QY4X3VwG4wtVoXZB9+L3r1Gp38DhELyHCtovqydRi7c1Ovb17eRGiQ/FD5s8JdU0Uy5A==", + "node_modules/@babel/helper-explode-assignable-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", + "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", "dev": true, - "requires": { - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", - "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "node_modules/@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" + "dependencies": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-get-function-arity": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", - "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "node_modules/@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", "dev": true, - "requires": { - "@babel/types": "^7.10.4" + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-hoist-variables": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz", - "integrity": "sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA==", + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.20.7.tgz", + "integrity": "sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw==", "dev": true, - "requires": { - "@babel/types": "^7.10.4" + "dependencies": { + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-member-expression-to-functions": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz", - "integrity": "sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q==", + "node_modules/@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", "dev": true, - "requires": { - "@babel/types": "^7.11.0" + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-module-imports": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", - "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "node_modules/@babel/helper-module-transforms": { + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", + "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", "dev": true, - "requires": { - "@babel/types": "^7.10.4" + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.10", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-module-transforms": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz", - "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==", + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", + "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", - "@babel/helper-simple-access": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/template": "^7.10.4", - "@babel/types": "^7.11.0", - "lodash": "^4.17.19" + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-optimise-call-expression": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", - "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", + "node_modules/@babel/helper-plugin-utils": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", "dev": true, - "requires": { - "@babel/types": "^7.10.4" + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", - "dev": true + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", + "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-wrap-function": "^7.18.9", + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } }, - "@babel/helper-regex": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.5.tgz", - "integrity": "sha512-68kdUAzDrljqBrio7DYAEgCoJHxppJOERHOgOrDN7WjOzP0ZQ1LsSDRXcemzVZaLvjaJsJEESb6qt+znNuENDg==", + "node_modules/@babel/helper-replace-supers": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz", + "integrity": "sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==", "dev": true, - "requires": { - "lodash": "^4.17.19" + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.20.7", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.7", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-remap-async-to-generator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.4.tgz", - "integrity": "sha512-86Lsr6NNw3qTNl+TBcF1oRZMaVzJtbWTyTko+CQL/tvNvcGYEFKbLXDPxtW0HKk3McNOk4KzY55itGWCAGK5tg==", + "node_modules/@babel/helper-simple-access": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-wrap-function": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "dependencies": { + "@babel/types": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-replace-supers": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", - "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", + "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.10.4", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "dependencies": { + "@babel/types": "^7.20.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-simple-access": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", - "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", "dev": true, - "requires": { - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz", - "integrity": "sha512-0XIdiQln4Elglgjbwo9wuJpL/K7AGCY26kmEt0+pRP0TAj4jjyNq1MjoRvikrTVqKcx4Gysxt4cXvVFXP/JO2Q==", + "node_modules/@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", "dev": true, - "requires": { - "@babel/types": "^7.11.0" + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-split-export-declaration": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", - "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "dev": true, - "requires": { - "@babel/types": "^7.11.0" + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-validator-identifier": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", - "dev": true + "node_modules/@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, - "@babel/helper-wrap-function": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz", - "integrity": "sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug==", + "node_modules/@babel/helper-wrap-function": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz", + "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==", "dev": true, - "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "dependencies": { + "@babel/helper-function-name": "^7.19.0", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helpers": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz", - "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==", + "node_modules/@babel/helpers": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.13.tgz", + "integrity": "sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==", "dev": true, - "requires": { - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "dependencies": { + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.13", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "dependencies": { - "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" - } - }, - "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 - } + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" } }, - "@babel/parser": { - "version": "7.11.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.3.tgz", - "integrity": "sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==", + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz", - "integrity": "sha512-cNMCVezQbrRGvXJwm9fu/1sJj9bHdGAgKodZdLqOQIpfoH3raqmRPBM17+lh7CzhiKRRBrGtZL9WcjxSoGYUSg==", + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-remap-async-to-generator": "^7.10.4", - "@babel/plugin-syntax-async-generators": "^7.8.0" + "engines": { + "node": ">=0.8.0" } }, - "@babel/plugin-proposal-class-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.4.tgz", - "integrity": "sha512-vhwkEROxzcHGNu2mzUC0OFFNXdZ4M23ib8aRRcJSsW8BZK9pQMD7QB7csl97NBbgGZO7ZyHUyKDnxzOaP4IrCg==", + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "engines": { + "node": ">=4" } }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz", - "integrity": "sha512-up6oID1LeidOOASNXgv/CFbgBqTuKJ0cJjz6An5tWD+NVBNlp3VNSBxv2ZdU7SYl3NxJC7agAQDApZusV6uFwQ==", + "node_modules/@babel/highlight/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==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.20.15", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.15.tgz", + "integrity": "sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-dynamic-import": "^7.8.0" + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" } }, - "@babel/plugin-proposal-export-namespace-from": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.10.4.tgz", - "integrity": "sha512-aNdf0LY6/3WXkhh0Fdb6Zk9j1NMD8ovj3F6r0+3j837Pn1S1PdNtcwJ5EG9WkVPNHPxyJDaxMaAOVq4eki0qbg==", + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.18.6", + "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.18.6.tgz", + "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz", + "integrity": "sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/plugin-proposal-optional-chaining": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-proposal-async-generator-functions": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz", + "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-remap-async-to-generator": "^7.18.9", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-class-static-block": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.20.7.tgz", + "integrity": "sha512-AveGOoi9DAjUYYuUAG//Ig69GlazLnoyzMw68VCDux+c1tsnnH/OkYcpz/5xzMkEFC6UxjR5Gw1c+iY2wOGVeQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.20.7", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-proposal-dynamic-import": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", + "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-export-namespace-from": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", + "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-json-strings": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz", - "integrity": "sha512-fCL7QF0Jo83uy1K0P2YXrfX11tj3lkpN7l4dMv9Y9VkowkhkQDwFHFd8IiwyK5MZjE8UpbgokkgtcReH88Abaw==", + "node_modules/@babel/plugin-proposal-json-strings": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", + "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.0" + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.11.0.tgz", - "integrity": "sha512-/f8p4z+Auz0Uaf+i8Ekf1iM7wUNLcViFUGiPxKeXvxTSl63B875YPiVdUDdem7hREcI0E0kSpEhS8tF5RphK7Q==", + "node_modules/@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz", + "integrity": "sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz", - "integrity": "sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw==", + "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.4.tgz", - "integrity": "sha512-73/G7QoRoeNkLZFxsoCCvlg4ezE4eM+57PnOqgaPOozd5myfj7p0muD1mRVJvbUWbOzD+q3No2bWbaKy+DJ8DA==", + "node_modules/@babel/plugin-proposal-numeric-separator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", + "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.11.0.tgz", - "integrity": "sha512-wzch41N4yztwoRw0ak+37wxwJM2oiIiy6huGCoqkvSTA9acYWcPfn9Y4aJqmFFJ70KTJUu29f3DQ43uJ9HXzEA==", + "node_modules/@babel/plugin-proposal-object-rest-spread": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", + "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-transform-parameters": "^7.10.4" + "dependencies": { + "@babel/compat-data": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz", - "integrity": "sha512-LflT6nPh+GK2MnFiKDyLiqSqVHkQnVf7hdoAvyTnnKj9xB3docGRsdPuxp6qqqW19ifK3xgc9U5/FwrSaCNX5g==", + "node_modules/@babel/plugin-proposal-optional-catch-binding": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", + "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.11.0.tgz", - "integrity": "sha512-v9fZIu3Y8562RRwhm1BbMRxtqZNFmFA2EG+pT2diuU8PT3H6T/KXoZ54KgYisfOFZHV6PfvAiBIZ9Rcz+/JCxA==", + "node_modules/@babel/plugin-proposal-optional-chaining": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.20.7.tgz", + "integrity": "sha512-T+A7b1kfjtRM51ssoOfS1+wbyCVqorfyZhT99TvxxLMirPShD8CzKMRepMlCBGM5RpHMbn8s+5MMHnPstJH6mQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.0" + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-private-methods": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.4.tgz", - "integrity": "sha512-wh5GJleuI8k3emgTg5KkJK6kHNsGEr0uBTDBuQUBJwckk9xs1ez79ioheEVVxMLyPscB0LfkbVHslQqIzWV6Bw==", + "node_modules/@babel/plugin-proposal-private-methods": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", + "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.4.tgz", - "integrity": "sha512-H+3fOgPnEXFL9zGYtKQe4IDOPKYlZdF1kqFDQRRb8PK4B8af1vAGK04tF5iQAAsui+mHNBQSAtd2/ndEDe9wuA==", + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz", + "integrity": "sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==", "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.20.5", + "@babel/helper-plugin-utils": "^7.20.2", + "@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-proposal-unicode-property-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", + "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-async-generators": { + "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, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-class-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz", - "integrity": "sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA==", + "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, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "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" } }, - "@babel/plugin-syntax-dynamic-import": { + "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, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-export-namespace-from": { + "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, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", + "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-json-strings": { + "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, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-jsx": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.4.tgz", - "integrity": "sha512-KCg9mio9jwiARCB7WAcQ7Y1q+qicILjoK8LP/VkPkEKaf5dkaZZK1EcTe91a3JJlZ3qy6L5s9X52boEYi8DM9g==", + "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, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-logical-assignment-operators": { + "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, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-nullish-coalescing-operator": { + "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, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-numeric-separator": { + "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, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-object-rest-spread": { + "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, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-optional-catch-binding": { + "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, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-optional-chaining": { + "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, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.4.tgz", - "integrity": "sha512-ni1brg4lXEmWyafKr0ccFWkJG0CeMt4WV1oyeBW6EFObF4oOHclbkj5cARxAPQyAQ2UTuplJyK4nfkXIMMFvsQ==", + "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, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz", - "integrity": "sha512-9J/oD1jV0ZCBcgnoFWFq1vJd4msoKb/TCpGNFyyLt0zABdcvgK3aYikZ8HjzB14c26bc7E3Q1yugpwGy2aTPNA==", + "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, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.4.tgz", - "integrity": "sha512-F6nREOan7J5UXTLsDsZG3DXmZSVofr2tGNwfdrVwkDWHfQckbQXnXSPfD7iO+c/2HGqycwyLST3DnZ16n+cBJQ==", + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz", + "integrity": "sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==", "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-remap-async-to-generator": "^7.10.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.4.tgz", - "integrity": "sha512-WzXDarQXYYfjaV1szJvN3AD7rZgZzC1JtjJZ8dMHUyiK8mxPRahynp14zzNjU3VkPqPsO38CzxiWO1c9ARZ8JA==", + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz", + "integrity": "sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-remap-async-to-generator": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-block-scoping": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.11.1.tgz", - "integrity": "sha512-00dYeDE0EVEHuuM+26+0w/SCL0BH2Qy7LwHuI4Hi4MH5gkC8/AqMN5uWFJIsoXZrAphiMm1iXzBw6L2T+eA0ew==", + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", + "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz", - "integrity": "sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-define-map": "^7.10.4", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.10.4", - "globals": "^11.1.0" + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-computed-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.4.tgz", - "integrity": "sha512-JFwVDXcP/hM/TbyzGq3l/XWGut7p46Z3QvqFMXTfk6/09m7xZHJUN9xHfsv7vqqD4YnfI5ueYdSJtXqqBLyjBw==", + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.20.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.15.tgz", + "integrity": "sha512-Vv4DMZ6MiNOhu/LdaZsT/bsLRxgL94d269Mv4R/9sp6+Mp++X/JqypZYypJXLlM4mlL352/Egzbzr98iABH1CA==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-destructuring": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz", - "integrity": "sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA==", + "node_modules/@babel/plugin-transform-classes": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.7.tgz", + "integrity": "sha512-LWYbsiXTPKl+oBlXUGlwNlJZetXD5Am+CyBdqhPsDVjM9Jc8jwBJFrKhHf900Kfk2eZG1y9MAG3UNajol7A4VQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-replace-supers": "^7.20.7", + "@babel/helper-split-export-declaration": "^7.18.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.4.tgz", - "integrity": "sha512-ZEAVvUTCMlMFAbASYSVQoxIbHm2OkG2MseW6bV2JjIygOjdVv8tuxrCTzj1+Rynh7ODb8GivUy7dzEXzEhuPaA==", + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz", + "integrity": "sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==", "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/template": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.4.tgz", - "integrity": "sha512-GL0/fJnmgMclHiBTTWXNlYjYsA7rDrtsazHG6mglaGSTh0KsrW04qml+Bbz9FL0LcJIRwBWL5ZqlNHKTkU3xAA==", + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.7.tgz", + "integrity": "sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz", - "integrity": "sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw==", + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", + "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", "dev": true, - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "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-0" } }, - "@babel/plugin-transform-for-of": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.4.tgz", - "integrity": "sha512-ItdQfAzu9AlEqmusA/65TqJ79eRcgGmpPPFvBnGILXZH975G0LNjP1yjHvGgfuCxqrPPueXOPe+FsvxmxKiHHQ==", + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", + "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.4.tgz", - "integrity": "sha512-OcDCq2y5+E0dVD5MagT5X+yTRbcvFjDI2ZVAottGH6tzqjx/LKpgkUepu3hp/u4tZBzxxpNGwLsAvGBvQ2mJzg==", + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", + "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", "dev": true, - "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-literals": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.4.tgz", - "integrity": "sha512-Xd/dFSTEVuUWnyZiMu76/InZxLTYilOSr1UlHV+p115Z/Le2Fi1KXkJUYz0b42DfndostYlPub3m8ZTQlMaiqQ==", + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", + "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.4.tgz", - "integrity": "sha512-0bFOvPyAoTBhtcJLr9VcwZqKmSjFml1iVxvPL0ReomGU53CX53HsM4h2SzckNdkQcHox1bpAqzxBI1Y09LlBSw==", + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", + "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-modules-amd": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.5.tgz", - "integrity": "sha512-elm5uruNio7CTLFItVC/rIzKLfQ17+fX7EVz5W0TMgIHFo1zY0Ozzx+lgwhL4plzl8OzVn6Qasx5DeEFyoNiRw==", + "node_modules/@babel/plugin-transform-literals": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", + "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.10.5", - "@babel/helper-plugin-utils": "^7.10.4", - "babel-plugin-dynamic-import-node": "^2.3.3" + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz", - "integrity": "sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w==", + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", + "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-simple-access": "^7.10.4", - "babel-plugin-dynamic-import-node": "^2.3.3" + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.5.tgz", - "integrity": "sha512-f4RLO/OL14/FP1AEbcsWMzpbUz6tssRaeQg11RH1BP/XnPpRoVwgeYViMFacnkaw4k4wjRSjn3ip1Uw9TaXuMw==", + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz", + "integrity": "sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==", "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.10.4", - "@babel/helper-module-transforms": "^7.10.5", - "@babel/helper-plugin-utils": "^7.10.4", - "babel-plugin-dynamic-import-node": "^2.3.3" + "dependencies": { + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-modules-umd": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz", - "integrity": "sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA==", + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.20.11.tgz", + "integrity": "sha512-S8e1f7WQ7cimJQ51JkAaDrEtohVEitXjgCGAS2N8S31Y42E+kWwfSz83LYz57QdBm7q9diARVqanIaH2oVgQnw==", "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-simple-access": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.4.tgz", - "integrity": "sha512-V6LuOnD31kTkxQPhKiVYzYC/Jgdq53irJC/xBSmqcNcqFGV+PER4l6rU5SH2Vl7bH9mLDHcc0+l9HUOe4RNGKA==", + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz", + "integrity": "sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==", "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4" + "dependencies": { + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-validator-identifier": "^7.19.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-new-target": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.4.tgz", - "integrity": "sha512-YXwWUDAH/J6dlfwqlWsztI2Puz1NtUAubXhOPLQ5gjR/qmQ5U96DY4FQO8At33JN4XPBhrjB8I4eMmLROjjLjw==", + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", + "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-object-super": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.4.tgz", - "integrity": "sha512-5iTw0JkdRdJvr7sY0vHqTpnruUpTea32JHmq/atIWqsnNussbRzjEDyWep8UNztt1B5IusBYg8Irb0bLbiEBCQ==", + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz", + "integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4" + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.20.5", + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/plugin-transform-parameters": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.5.tgz", - "integrity": "sha512-xPHwUj5RdFV8l1wuYiu5S9fqWGM2DrYc24TMvUiRrPVm+SM3XeqU9BcokQX/kEUe+p2RBwy+yoiR1w/Blq6ubw==", + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", + "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-property-literals": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.4.tgz", - "integrity": "sha512-ofsAcKiUxQ8TY4sScgsGeR2vJIsfrzqvFb9GvJ5UdXDzl+MyYCaBj/FGzXuv7qE0aJcjWMILny1epqelnFlz8g==", + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", + "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-react-display-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.10.4.tgz", - "integrity": "sha512-Zd4X54Mu9SBfPGnEcaGcOrVAYOtjT2on8QZkLKEq1S/tHexG39d9XXGZv19VfRrDjPJzFmPfTAqOQS1pfFOujw==", + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.7.tgz", + "integrity": "sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-react-jsx": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.10.4.tgz", - "integrity": "sha512-L+MfRhWjX0eI7Js093MM6MacKU4M6dnCRa/QPDwYMxjljzSCzzlzKzj9Pk4P3OtrPcxr2N3znR419nr3Xw+65A==", + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", + "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", "dev": true, - "requires": { - "@babel/helper-builder-react-jsx": "^7.10.4", - "@babel/helper-builder-react-jsx-experimental": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-jsx": "^7.10.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-react-jsx-development": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.10.4.tgz", - "integrity": "sha512-RM3ZAd1sU1iQ7rI2dhrZRZGv0aqzNQMbkIUCS1txYpi9wHQ2ZHNjo5TwX+UD6pvFW4AbWqLVYvKy5qJSAyRGjQ==", + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz", + "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==", "dev": true, - "requires": { - "@babel/helper-builder-react-jsx-experimental": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-jsx": "^7.10.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-react-jsx-self": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.10.4.tgz", - "integrity": "sha512-yOvxY2pDiVJi0axdTWHSMi5T0DILN+H+SaeJeACHKjQLezEzhLx9nEF9xgpBLPtkZsks9cnb5P9iBEi21En3gg==", + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.20.13.tgz", + "integrity": "sha512-MmTZx/bkUrfJhhYAYt3Urjm+h8DQGrPrnKQ94jLo7NLuOU+T89a7IByhKmrb8SKhrIYIQ0FN0CHMbnFRen4qNw==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-jsx": "^7.10.4" + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-jsx": "^7.18.6", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-react-jsx-source": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.10.5.tgz", - "integrity": "sha512-wTeqHVkN1lfPLubRiZH3o73f4rfon42HpgxUSs86Nc+8QIcm/B9s8NNVXu/gwGcOyd7yDib9ikxoDLxJP0UiDA==", + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz", + "integrity": "sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-jsx": "^7.10.4" + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-react-pure-annotations": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.10.4.tgz", - "integrity": "sha512-+njZkqcOuS8RaPakrnR9KvxjoG1ASJWpoIv/doyWngId88JoFlPlISenGXjrVacZUIALGUr6eodRs1vmPnF23A==", + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz", + "integrity": "sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==", "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-regenerator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz", - "integrity": "sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw==", + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz", + "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==", "dev": true, - "requires": { - "regenerator-transform": "^0.14.2" + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", + "regenerator-transform": "^0.15.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-reserved-words": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.4.tgz", - "integrity": "sha512-hGsw1O6Rew1fkFbDImZIEqA8GoidwTAilwCyWqLBM9f+e/u/sQMQu7uX6dyokfOayRuuVfKOW4O7HvaBWM+JlQ==", + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", + "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz", - "integrity": "sha512-AC2K/t7o07KeTIxMoHneyX90v3zkm5cjHJEokrPEAGEy3UCp8sLKfnfOIGdZ194fyN4wfX/zZUWT9trJZ0qc+Q==", + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", + "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-spread": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.11.0.tgz", - "integrity": "sha512-UwQYGOqIdQJe4aWNyS7noqAnN2VbaczPLiEtln+zPowRNlD+79w3oi2TWfYe0eZgd+gjZCbsydN7lzWysDt+gw==", + "node_modules/@babel/plugin-transform-spread": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz", + "integrity": "sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0" + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz", - "integrity": "sha512-Ddy3QZfIbEV0VYcVtFDCjeE4xwVTJWTmUtorAJkn6u/92Z/nWJNV+mILyqHKrUxXYKA2EoCilgoPePymKL4DvQ==", + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", + "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-regex": "^7.10.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-template-literals": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.5.tgz", - "integrity": "sha512-V/lnPGIb+KT12OQikDvgSuesRX14ck5FfJXt6+tXhdkJ+Vsd0lDCVtF6jcB4rNClYFzaB2jusZ+lNISDk2mMMw==", + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", + "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.4.tgz", - "integrity": "sha512-QqNgYwuuW0y0H+kUE/GWSR45t/ccRhe14Fs/4ZRouNNQsyd4o3PG4OtHiIrepbM2WKUBDAXKCAK/Lk4VhzTaGA==", + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", + "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-unicode-escapes": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.4.tgz", - "integrity": "sha512-y5XJ9waMti2J+e7ij20e+aH+fho7Wb7W8rNuu72aKRwCHFqQdhkdU2lo3uZ9tQuboEJcUFayXdARhcxLQ3+6Fg==", + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", + "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.4.tgz", - "integrity": "sha512-wNfsc4s8N2qnIwpO/WP2ZiSyjfpTamT2C9V9FDH/Ljub9zw6P3SjkXcFmc0RQUt96k2fmIvtla2MMjgTwIAC+A==", + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", + "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "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-0" } }, - "@babel/polyfill": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.10.4.tgz", - "integrity": "sha512-8BYcnVqQ5kMD2HXoHInBH7H1b/uP3KdnwCYXOqFnXqguOyuu443WXusbIUbWEfY3Z0Txk0M1uG/8YuAMhNl6zg==", + "node_modules/@babel/polyfill": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.12.1.tgz", + "integrity": "sha512-X0pi0V6gxLi6lFZpGmeNa4zxtwEmCs42isWLNjZZDE0Y8yVfgu0T2OAHlzBbdYlqbW/YXVvoBHpATEM+goCj8g==", + "deprecated": "🚨 This package has been deprecated in favor of separate inclusion of a polyfill and regenerator-runtime (when needed). See the @babel/polyfill docs (https://babeljs.io/docs/en/babel-polyfill) for more information.", "dev": true, - "requires": { + "dependencies": { "core-js": "^2.6.5", "regenerator-runtime": "^0.13.4" } }, - "@babel/preset-env": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.11.0.tgz", - "integrity": "sha512-2u1/k7rG/gTh02dylX2kL3S0IJNF+J6bfDSp4DI2Ma8QN6Y9x9pmAax59fsCk6QUQG0yqH47yJWA+u1I1LccAg==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.11.0", - "@babel/helper-compilation-targets": "^7.10.4", - "@babel/helper-module-imports": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-proposal-async-generator-functions": "^7.10.4", - "@babel/plugin-proposal-class-properties": "^7.10.4", - "@babel/plugin-proposal-dynamic-import": "^7.10.4", - "@babel/plugin-proposal-export-namespace-from": "^7.10.4", - "@babel/plugin-proposal-json-strings": "^7.10.4", - "@babel/plugin-proposal-logical-assignment-operators": "^7.11.0", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4", - "@babel/plugin-proposal-numeric-separator": "^7.10.4", - "@babel/plugin-proposal-object-rest-spread": "^7.11.0", - "@babel/plugin-proposal-optional-catch-binding": "^7.10.4", - "@babel/plugin-proposal-optional-chaining": "^7.11.0", - "@babel/plugin-proposal-private-methods": "^7.10.4", - "@babel/plugin-proposal-unicode-property-regex": "^7.10.4", - "@babel/plugin-syntax-async-generators": "^7.8.0", - "@babel/plugin-syntax-class-properties": "^7.10.4", - "@babel/plugin-syntax-dynamic-import": "^7.8.0", + "node_modules/@babel/preset-env": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz", + "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.20.1", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-async-generator-functions": "^7.20.1", + "@babel/plugin-proposal-class-properties": "^7.18.6", + "@babel/plugin-proposal-class-static-block": "^7.18.6", + "@babel/plugin-proposal-dynamic-import": "^7.18.6", + "@babel/plugin-proposal-export-namespace-from": "^7.18.9", + "@babel/plugin-proposal-json-strings": "^7.18.6", + "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", + "@babel/plugin-proposal-numeric-separator": "^7.18.6", + "@babel/plugin-proposal-object-rest-spread": "^7.20.2", + "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", + "@babel/plugin-proposal-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-private-methods": "^7.18.6", + "@babel/plugin-proposal-private-property-in-object": "^7.18.6", + "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", + "@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-json-strings": "^7.8.0", + "@babel/plugin-syntax-import-assertions": "^7.20.0", + "@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.0", + "@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.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.10.4", - "@babel/plugin-transform-arrow-functions": "^7.10.4", - "@babel/plugin-transform-async-to-generator": "^7.10.4", - "@babel/plugin-transform-block-scoped-functions": "^7.10.4", - "@babel/plugin-transform-block-scoping": "^7.10.4", - "@babel/plugin-transform-classes": "^7.10.4", - "@babel/plugin-transform-computed-properties": "^7.10.4", - "@babel/plugin-transform-destructuring": "^7.10.4", - "@babel/plugin-transform-dotall-regex": "^7.10.4", - "@babel/plugin-transform-duplicate-keys": "^7.10.4", - "@babel/plugin-transform-exponentiation-operator": "^7.10.4", - "@babel/plugin-transform-for-of": "^7.10.4", - "@babel/plugin-transform-function-name": "^7.10.4", - "@babel/plugin-transform-literals": "^7.10.4", - "@babel/plugin-transform-member-expression-literals": "^7.10.4", - "@babel/plugin-transform-modules-amd": "^7.10.4", - "@babel/plugin-transform-modules-commonjs": "^7.10.4", - "@babel/plugin-transform-modules-systemjs": "^7.10.4", - "@babel/plugin-transform-modules-umd": "^7.10.4", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.10.4", - "@babel/plugin-transform-new-target": "^7.10.4", - "@babel/plugin-transform-object-super": "^7.10.4", - "@babel/plugin-transform-parameters": "^7.10.4", - "@babel/plugin-transform-property-literals": "^7.10.4", - "@babel/plugin-transform-regenerator": "^7.10.4", - "@babel/plugin-transform-reserved-words": "^7.10.4", - "@babel/plugin-transform-shorthand-properties": "^7.10.4", - "@babel/plugin-transform-spread": "^7.11.0", - "@babel/plugin-transform-sticky-regex": "^7.10.4", - "@babel/plugin-transform-template-literals": "^7.10.4", - "@babel/plugin-transform-typeof-symbol": "^7.10.4", - "@babel/plugin-transform-unicode-escapes": "^7.10.4", - "@babel/plugin-transform-unicode-regex": "^7.10.4", - "@babel/preset-modules": "^0.1.3", - "@babel/types": "^7.11.0", - "browserslist": "^4.12.0", - "core-js-compat": "^3.6.2", - "invariant": "^2.2.2", - "levenary": "^1.1.1", - "semver": "^5.5.0" + "@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-transform-arrow-functions": "^7.18.6", + "@babel/plugin-transform-async-to-generator": "^7.18.6", + "@babel/plugin-transform-block-scoped-functions": "^7.18.6", + "@babel/plugin-transform-block-scoping": "^7.20.2", + "@babel/plugin-transform-classes": "^7.20.2", + "@babel/plugin-transform-computed-properties": "^7.18.9", + "@babel/plugin-transform-destructuring": "^7.20.2", + "@babel/plugin-transform-dotall-regex": "^7.18.6", + "@babel/plugin-transform-duplicate-keys": "^7.18.9", + "@babel/plugin-transform-exponentiation-operator": "^7.18.6", + "@babel/plugin-transform-for-of": "^7.18.8", + "@babel/plugin-transform-function-name": "^7.18.9", + "@babel/plugin-transform-literals": "^7.18.9", + "@babel/plugin-transform-member-expression-literals": "^7.18.6", + "@babel/plugin-transform-modules-amd": "^7.19.6", + "@babel/plugin-transform-modules-commonjs": "^7.19.6", + "@babel/plugin-transform-modules-systemjs": "^7.19.6", + "@babel/plugin-transform-modules-umd": "^7.18.6", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", + "@babel/plugin-transform-new-target": "^7.18.6", + "@babel/plugin-transform-object-super": "^7.18.6", + "@babel/plugin-transform-parameters": "^7.20.1", + "@babel/plugin-transform-property-literals": "^7.18.6", + "@babel/plugin-transform-regenerator": "^7.18.6", + "@babel/plugin-transform-reserved-words": "^7.18.6", + "@babel/plugin-transform-shorthand-properties": "^7.18.6", + "@babel/plugin-transform-spread": "^7.19.0", + "@babel/plugin-transform-sticky-regex": "^7.18.6", + "@babel/plugin-transform-template-literals": "^7.18.9", + "@babel/plugin-transform-typeof-symbol": "^7.18.9", + "@babel/plugin-transform-unicode-escapes": "^7.18.10", + "@babel/plugin-transform-unicode-regex": "^7.18.6", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.20.2", + "babel-plugin-polyfill-corejs2": "^0.3.3", + "babel-plugin-polyfill-corejs3": "^0.6.0", + "babel-plugin-polyfill-regenerator": "^0.4.1", + "core-js-compat": "^3.25.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/preset-modules": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.3.tgz", - "integrity": "sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg==", + "node_modules/@babel/preset-modules": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", + "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", "dev": true, - "requires": { + "dependencies": { "@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" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/preset-react": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.10.4.tgz", - "integrity": "sha512-BrHp4TgOIy4M19JAfO1LhycVXOPWdDbTRep7eVyatf174Hff+6Uk53sDyajqZPu8W1qXRBiYOfIamek6jA7YVw==", + "node_modules/@babel/preset-react": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.18.6.tgz", + "integrity": "sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-transform-react-display-name": "^7.10.4", - "@babel/plugin-transform-react-jsx": "^7.10.4", - "@babel/plugin-transform-react-jsx-development": "^7.10.4", - "@babel/plugin-transform-react-jsx-self": "^7.10.4", - "@babel/plugin-transform-react-jsx-source": "^7.10.4", - "@babel/plugin-transform-react-pure-annotations": "^7.10.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-transform-react-display-name": "^7.18.6", + "@babel/plugin-transform-react-jsx": "^7.18.6", + "@babel/plugin-transform-react-jsx-development": "^7.18.6", + "@babel/plugin-transform-react-pure-annotations": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/register": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.10.5.tgz", - "integrity": "sha512-eYHdLv43nyvmPn9bfNfrcC4+iYNwdQ8Pxk1MFJuU/U5LpSYl/PH4dFMazCYZDFVi8ueG3shvO+AQfLrxpYulQw==", + "node_modules/@babel/register": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.18.9.tgz", + "integrity": "sha512-ZlbnXDcNYHMR25ITwwNKT88JiaukkdVj/nG7r3wnuXkOTHc60Uy05PwMCPre0hSkY68E6zK3xz+vUJSP2jWmcw==", "dev": true, - "requires": { + "dependencies": { + "clone-deep": "^4.0.1", "find-cache-dir": "^2.0.0", - "lodash": "^4.17.19", "make-dir": "^2.1.0", - "pirates": "^4.0.0", + "pirates": "^4.0.5", "source-map-support": "^0.5.16" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/runtime": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.2.tgz", - "integrity": "sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==", + "node_modules/@babel/runtime": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz", + "integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==", "dev": true, - "requires": { - "regenerator-runtime": "^0.13.4" + "dependencies": { + "regenerator-runtime": "^0.13.11" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/traverse": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", - "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.11.0", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.11.0", - "@babel/types": "^7.11.0", + "node_modules/@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.13.tgz", + "integrity": "sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.13", + "@babel/types": "^7.20.7", "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.19" + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/types": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", - "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "node_modules/@babel/types": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", + "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.19", + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, + "dependencies": { + "@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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, - "@mrmlnc/readdir-enhanced": { + "node_modules/@mrmlnc/readdir-enhanced": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", "dev": true, - "requires": { + "dependencies": { "call-me-maybe": "^1.0.1", "glob-to-regexp": "^0.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.scandir/node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" } }, - "@nodelib/fs.stat": { + "node_modules/@nodelib/fs.stat": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", - "dev": true + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } }, - "@sindresorhus/is": { + "node_modules/@sindresorhus/is": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "@types/cheerio": { - "version": "0.22.21", - "resolved": "https://registry.npmjs.org/@types/cheerio/-/cheerio-0.22.21.tgz", - "integrity": "sha512-aGI3DfswwqgKPiEOTaiHV2ZPC9KEhprpgEbJnv0fZl3SGX0cGgEva1126dGrMC6AJM6v/aihlUgJn9M5DbDZ/Q==", + "node_modules/@types/cheerio": { + "version": "0.22.31", + "resolved": "https://registry.npmjs.org/@types/cheerio/-/cheerio-0.22.31.tgz", + "integrity": "sha512-Kt7Cdjjdi2XWSfrZ53v4Of0wG3ZcmaegFXjMmz9tfNrZSkzzo36G0AL1YqSdcIA78Etjt6E609pt5h1xnQkPUw==", "dev": true, - "requires": { + "dependencies": { "@types/node": "*" } }, - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "node_modules/@types/node": { + "version": "18.11.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", + "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", "dev": true }, - "@types/node": { - "version": "14.6.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.6.0.tgz", - "integrity": "sha512-mikldZQitV94akrc4sCcSjtJfsTKt4p+e/s0AGscVA6XArQ9kFclP+ZiYUMnq987rc6QlYxXv/EivqlfSLxpKA==", + "node_modules/@types/q": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz", + "integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==", "dev": true }, - "@types/q": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", - "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==", - "dev": true - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "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==", "dev": true, - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" } }, - "address": { + "node_modules/address": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/airbnb-prop-types": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/airbnb-prop-types/-/airbnb-prop-types-2.16.0.tgz", + "integrity": "sha512-7WHOFolP/6cS96PhKNrslCLMYAI8yB1Pp6u6XmxozQOiZbsI5ycglZr5cHhBFfuRcQQjzCMith5ZPZdYiJCxUg==", + "dev": true, + "dependencies": { + "array.prototype.find": "^2.1.1", + "function.prototype.name": "^1.1.2", + "is-regex": "^1.1.0", + "object-is": "^1.1.2", + "object.assign": "^4.1.0", + "object.entries": "^1.1.2", + "prop-types": "^15.7.2", + "prop-types-exact": "^1.2.0", + "react-is": "^16.13.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + }, + "peerDependencies": { + "react": "^0.14 || ^15.0.0 || ^16.0.0-alpha" + } }, - "ajv": { - "version": "6.12.4", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz", - "integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==", + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "requires": { + "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" } }, - "alphanum-sort": { + "node_modules/alphanum-sort": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", - "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", - "dev": true - }, - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "integrity": "sha512-0FcBfdcmaumGPQ0qPn7Q5qTgz/ooXgIyp1rf8ik5bGX8mpE2YHjC0P/eyQvxu1GURYQgq9ozf2mteQ5ZD9YiyQ==", "dev": true }, - "ansi-red": { + "node_modules/ansi-red": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", - "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=", + "integrity": "sha512-ewaIr5y+9CUTGFwZfpECUbFlGcC0GCw1oqR9RI6h1gQCd9Aj2GxSckCnPsVJnmfMZbwFYE+leZGASgkWl06Jow==", "dev": true, - "requires": { + "dependencies": { "ansi-wrap": "0.1.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "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==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "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==", + "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, - "requires": { - "color-convert": "^1.9.0" + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "ansi-wrap": { + "node_modules/ansi-wrap": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", - "dev": true - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": 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, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } + "integrity": "sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "arch": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.1.2.tgz", - "integrity": "sha512-NTBIIbAfkJeIletyABbVtdPgeKfDafR+1mZV/AyyfC1UkVkp9iUjV+wwmqtUgphHYajbI86jejBJp5e+jkGTiQ==", - "dev": true + "node_modules/arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "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" + } + ] }, - "archive-type": { + "node_modules/archive-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz", - "integrity": "sha1-+S5yIzBW38aWlHJ0nCZ72wRrHXA=", + "integrity": "sha512-zV4Ky0v1F8dBrdYElwTvQhweQ0P7Kwc1aluqJsYtOBP01jXcWCyW2IEfI1YiqsG+Iy7ZR+o5LF1N+PGECBxHWA==", "dev": true, - "requires": { + "dependencies": { "file-type": "^4.2.0" }, - "dependencies": { - "file-type": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz", - "integrity": "sha1-G2AOX8ofvcboDApwxxyNul95BsU=", - "dev": true - } + "engines": { + "node": ">=4" + } + }, + "node_modules/archive-type/node_modules/file-type": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz", + "integrity": "sha512-f2UbFQEk7LXgWpi5ntcO86OeA/cC80fuDDDaX/fZ2ZGel+AF7leRQqBBW1eJNiiQkrZlAoM6P+VYP5P6bOlDEQ==", + "dev": true, + "engines": { + "node": ">=4" } }, - "argparse": { + "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, - "requires": { + "dependencies": { "sprintf-js": "~1.0.2" } }, - "arr-diff": { + "node_modules/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 + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "arr-flatten": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "arr-union": { + "node_modules/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 + "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "array-find-index": { + "node_modules/array-find-index": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", - "dev": true + "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "array-flatten": { + "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "dev": true }, - "array-union": { + "node_modules/array-union": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", "dev": true, - "requires": { + "dependencies": { "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "array-uniq": { + "node_modules/array-uniq": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "array-unique": { + "node_modules/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 + "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array.prototype.filter": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array.prototype.filter/-/array.prototype.filter-1.0.2.tgz", + "integrity": "sha512-us+UrmGOilqttSOgoWZTpOvHu68vZT2YCjc/H4vhu56vzZpaDFBhB+Se2UwqWzMKbDv7Myq5M5pcZLAtUvTQdQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.find": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.2.1.tgz", + "integrity": "sha512-I2ri5Z9uMpMvnsNrHre9l3PaX+z9D0/z6F7Yt2u15q7wt0I62g5kX6xUKR1SJiefgG+u2/gJUmM8B47XRvQR6w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", + "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.reduce": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz", + "integrity": "sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "arrify": { + "node_modules/arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "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==", "dev": true, - "requires": { + "dependencies": { "safer-buffer": "~2.1.0" } }, - "assert-plus": { + "node_modules/assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "engines": { + "node": ">=0.8" + } }, - "assign-symbols": { + "node_modules/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 + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", "dev": true, - "requires": { + "dependencies": { "lodash": "^4.17.14" } }, - "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 - }, - "asynckit": { + "node_modules/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==", "dev": true }, - "atob": { + "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/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 + "dev": true, + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } }, - "autolinker": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-0.28.1.tgz", - "integrity": "sha1-BlK0kYgYefB3XazgzcoyM5QqTkc=", + "node_modules/autolinker": { + "version": "3.16.2", + "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-3.16.2.tgz", + "integrity": "sha512-JiYl7j2Z19F9NdTmirENSUUIIL/9MytEWtmzhfmsKPCp9E+G35Y0UNCMoM9tFigxT59qSc8Ml2dlZXOCVTYwuA==", "dev": true, - "requires": { - "gulp-header": "^1.7.1" + "dependencies": { + "tslib": "^2.3.0" } }, - "autoprefixer": { - "version": "9.8.6", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.6.tgz", - "integrity": "sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==", + "node_modules/autoprefixer": { + "version": "9.8.8", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz", + "integrity": "sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==", "dev": true, - "requires": { + "dependencies": { "browserslist": "^4.12.0", "caniuse-lite": "^1.0.30001109", - "colorette": "^1.2.1", "normalize-range": "^0.1.2", "num2fraction": "^1.2.2", + "picocolors": "^0.2.1", "postcss": "^7.0.32", "postcss-value-parser": "^4.1.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "aws-sign2": { + "node_modules/aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, + "engines": { + "node": "*" + } }, - "aws4": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.1.tgz", - "integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==", + "node_modules/aws4": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", "dev": true }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", + "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" + "dependencies": { + "@babel/compat-data": "^7.17.7", + "@babel/helper-define-polyfill-provider": "^0.3.3", + "semver": "^6.1.1" }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", + "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", + "dev": true, "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "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 - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } + "@babel/helper-define-polyfill-provider": "^0.3.3", + "core-js-compat": "^3.25.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "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==", + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", + "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", "dev": true, - "requires": { - "object.assign": "^4.1.0" + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.3.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babylon": { + "node_modules/babylon": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true + "dev": true, + "bin": { + "babylon": "bin/babylon.js" + } }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "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==", "dev": true }, - "base": { + "node_modules/base": { "version": "0.11.2", "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, - "requires": { + "dependencies": { "cache-base": "^1.0.1", "class-utils": "^0.3.5", "component-emitter": "^1.2.1", @@ -1560,157 +2446,195 @@ "mixin-deep": "^1.2.0", "pascalcase": "^0.1.1" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, "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, - "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, - "requires": { - "kind-of": "^6.0.0" - } + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "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, - "requires": { - "kind-of": "^6.0.0" - } + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "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, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } + { + "type": "consulting", + "url": "https://feross.org/support" } - } + ] }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { + "node_modules/bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", "dev": true, - "requires": { + "dependencies": { "tweetnacl": "^0.14.3" } }, - "big.js": { + "node_modules/big-integer": { + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true + "dev": true, + "engines": { + "node": "*" + } }, - "bin-build": { + "node_modules/bin-build": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bin-build/-/bin-build-3.0.0.tgz", "integrity": "sha512-jcUOof71/TNAI2uM5uoUaDq2ePcVBQ3R/qhxAz1rX7UfvduAL/RXD3jXzvn8cVcDJdGVkiR1shal3OH0ImpuhA==", "dev": true, - "requires": { + "dependencies": { "decompress": "^4.0.0", "download": "^6.2.2", "execa": "^0.7.0", "p-map-series": "^1.0.0", "tempfile": "^2.0.0" + }, + "engines": { + "node": ">=4" } }, - "bin-check": { + "node_modules/bin-check": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bin-check/-/bin-check-4.1.0.tgz", "integrity": "sha512-b6weQyEUKsDGFlACWSIOfveEnImkJyK/FGW6FAG42loyoquvjdtOIqO6yBFzHyqyVVhNgNkQxxx09SFLK28YnA==", "dev": true, - "requires": { + "dependencies": { "execa": "^0.7.0", "executable": "^4.1.0" + }, + "engines": { + "node": ">=4" } }, - "bin-version": { + "node_modules/bin-version": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bin-version/-/bin-version-3.1.0.tgz", "integrity": "sha512-Mkfm4iE1VFt4xd4vH+gx+0/71esbfus2LsnCGe8Pi4mndSPyT+NGES/Eg99jx8/lUGWfu3z2yuB/bt5UB+iVbQ==", "dev": true, - "requires": { + "dependencies": { "execa": "^1.0.0", "find-versions": "^3.0.0" }, - "dependencies": { - "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, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - } + "engines": { + "node": ">=6" } }, - "bin-version-check": { + "node_modules/bin-version-check": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/bin-version-check/-/bin-version-check-4.0.0.tgz", "integrity": "sha512-sR631OrhC+1f8Cvs8WyVWOA33Y8tgwjETNPyyD/myRBXLkfS/vl74FmH/lFcRl9KY3zwGh7jFhvyk9vV3/3ilQ==", "dev": true, - "requires": { + "dependencies": { "bin-version": "^3.0.0", "semver": "^5.6.0", "semver-truncate": "^1.1.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/bin-version-check/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/bin-version/node_modules/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, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/bin-version/node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/bin-version/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/bin-version/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" } }, - "bin-wrapper": { + "node_modules/bin-wrapper": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bin-wrapper/-/bin-wrapper-4.1.0.tgz", "integrity": "sha512-hfRmo7hWIXPkbpi0ZltboCMVrU+0ClXR/JgbCKKjlDjQf6igXa7OwdqNcFWQZPZTgiY7ZpzE3+LjjkLiTN2T7Q==", "dev": true, - "requires": { + "dependencies": { "bin-check": "^4.1.0", "bin-version-check": "^4.0.0", "download": "^7.1.0", @@ -1718,247 +2642,290 @@ "os-filter-obj": "^2.0.0", "pify": "^4.0.1" }, - "dependencies": { - "download": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/download/-/download-7.1.0.tgz", - "integrity": "sha512-xqnBTVd/E+GxJVrX5/eUJiLYjCGPwMpdL+jGhGU57BvtcA7wwhtHVbXBeUk51kOpW3S7Jn3BQbN9Q1R1Km2qDQ==", - "dev": true, - "requires": { - "archive-type": "^4.0.0", - "caw": "^2.0.1", - "content-disposition": "^0.5.2", - "decompress": "^4.2.0", - "ext-name": "^5.0.0", - "file-type": "^8.1.0", - "filenamify": "^2.0.0", - "get-stream": "^3.0.0", - "got": "^8.3.1", - "make-dir": "^1.2.0", - "p-event": "^2.1.0", - "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 - } - } - }, - "file-type": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-8.1.0.tgz", - "integrity": "sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ==", - "dev": true - }, - "got": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz", - "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==", - "dev": true, - "requires": { - "@sindresorhus/is": "^0.7.0", - "cacheable-request": "^2.1.1", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "into-stream": "^3.1.0", - "is-retry-allowed": "^1.1.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "mimic-response": "^1.0.0", - "p-cancelable": "^0.4.0", - "p-timeout": "^2.0.1", - "pify": "^3.0.0", - "safe-buffer": "^5.1.1", - "timed-out": "^4.0.1", - "url-parse-lax": "^3.0.0", - "url-to-options": "^1.0.1" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "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" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "p-cancelable": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", - "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==", - "dev": true - }, - "p-event": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz", - "integrity": "sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==", - "dev": true, - "requires": { - "p-timeout": "^2.0.1" - } - }, - "p-timeout": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", - "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", - "dev": true, - "requires": { - "p-finally": "^1.0.0" - } - }, - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true - }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "dev": true, - "requires": { - "prepend-http": "^2.0.0" - } - } + "engines": { + "node": ">=6" } }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bl": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", - "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "node_modules/bin-wrapper/node_modules/download": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/download/-/download-7.1.0.tgz", + "integrity": "sha512-xqnBTVd/E+GxJVrX5/eUJiLYjCGPwMpdL+jGhGU57BvtcA7wwhtHVbXBeUk51kOpW3S7Jn3BQbN9Q1R1Km2qDQ==", "dev": true, - "requires": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" + "dependencies": { + "archive-type": "^4.0.0", + "caw": "^2.0.1", + "content-disposition": "^0.5.2", + "decompress": "^4.2.0", + "ext-name": "^5.0.0", + "file-type": "^8.1.0", + "filenamify": "^2.0.0", + "get-stream": "^3.0.0", + "got": "^8.3.1", + "make-dir": "^1.2.0", + "p-event": "^2.1.0", + "pify": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "body": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz", - "integrity": "sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk=", + "node_modules/bin-wrapper/node_modules/download/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, - "requires": { + "engines": { + "node": ">=4" + } + }, + "node_modules/bin-wrapper/node_modules/file-type": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-8.1.0.tgz", + "integrity": "sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/bin-wrapper/node_modules/got": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz", + "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^0.7.0", + "cacheable-request": "^2.1.1", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "into-stream": "^3.1.0", + "is-retry-allowed": "^1.1.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "mimic-response": "^1.0.0", + "p-cancelable": "^0.4.0", + "p-timeout": "^2.0.1", + "pify": "^3.0.0", + "safe-buffer": "^5.1.1", + "timed-out": "^4.0.1", + "url-parse-lax": "^3.0.0", + "url-to-options": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/bin-wrapper/node_modules/got/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/bin-wrapper/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/bin-wrapper/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/bin-wrapper/node_modules/p-cancelable": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", + "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/bin-wrapper/node_modules/p-event": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz", + "integrity": "sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==", + "dev": true, + "dependencies": { + "p-timeout": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/bin-wrapper/node_modules/p-timeout": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", + "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", + "dev": true, + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/bin-wrapper/node_modules/prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/bin-wrapper/node_modules/url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", + "dev": true, + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==", + "dev": true, + "dependencies": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + }, + "engines": { + "node": "*" + } + }, + "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/bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==", + "dev": true + }, + "node_modules/body": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz", + "integrity": "sha512-chUsBxGRtuElD6fmw1gHLpvnKdVLK302peeFa9ZqAEk8TyzZ3fygLyUEDDPTJvL9+Bor0dIwn6ePOsRM2y0zQQ==", + "dev": true, + "dependencies": { "continuable-cache": "^0.3.1", "error": "^7.0.0", "raw-body": "~1.1.0", "safe-json-parse": "~1.0.1" - }, - "dependencies": { - "bytes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", - "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=", - "dev": true - }, - "raw-body": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", - "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=", - "dev": true, - "requires": { - "bytes": "1", - "string_decoder": "0.10" - } - }, - "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 - } } }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "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==", "dev": true, - "requires": { - "bytes": "3.1.0", + "dependencies": { + "bytes": "3.1.2", "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "dependencies": { - "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" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true - } + "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/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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/body/node_modules/bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", + "integrity": "sha512-/x68VkHLeTl3/Ll8IvxdwzhrT+IyKc52e/oyHhA2RwqPqswSnjVbSddfPRwAsJtbilMAPSRWwAlpxdYsSWOTKQ==", + "dev": true + }, + "node_modules/body/node_modules/raw-body": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", + "integrity": "sha512-WmJJU2e9Y6M5UzTOkHaM7xJGAPQD8PNzx3bAd2+uhZAim6wDk6dAZxPVYLF67XhbR4hmKGh33Lpmh4XWrCH5Mg==", + "dev": true, + "dependencies": { + "bytes": "1", + "string_decoder": "0.10" + }, + "engines": { + "node": ">= 0.8.0" } }, - "boolbase": { + "node_modules/body/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "dev": true + }, + "node_modules/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 }, - "brace-expansion": { + "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==", "dev": true, - "requires": { + "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "braces": { + "node_modules/braces": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, - "requires": { + "dependencies": { "arr-flatten": "^1.1.0", "array-unique": "^0.3.2", "extend-shallow": "^2.0.1", @@ -1970,86 +2937,171 @@ "split-string": "^3.0.2", "to-regex": "^3.0.1" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/braces/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dev": true, "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, - "requires": { - "is-extendable": "^0.1.0" - } - } + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "browserslist": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.0.tgz", - "integrity": "sha512-pUsXKAF2lVwhmtpeA3LJrZ76jXuusrNyhduuQs7CDFf9foT4Y38aQOserd2lMe5DSSrjf3fx34oHwryuvxAUgQ==", + "node_modules/braces/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001111", - "electron-to-chromium": "^1.3.523", - "escalade": "^3.0.2", - "node-releases": "^1.1.60" + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" } }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", + "node_modules/braces/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/browserslist": { + "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/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.0.2", - "ieee754": "^1.1.4" + "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" } }, - "buffer-alloc": { + "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, - "requires": { + "dependencies": { "buffer-alloc-unsafe": "^1.1.0", "buffer-fill": "^1.0.0" } }, - "buffer-alloc-unsafe": { + "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 }, - "buffer-crc32": { + "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } }, - "buffer-fill": { + "node_modules/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-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true + "node_modules/buffer-indexof-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", + "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==", + "dev": true, + "engines": { + "node": ">=0.2.0" + } }, - "cache-base": { + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/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, - "requires": { + "dependencies": { "collection-visit": "^1.0.0", "component-emitter": "^1.2.1", "get-value": "^2.0.6", @@ -2059,14 +3111,17 @@ "to-object-path": "^0.3.0", "union-value": "^1.0.0", "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "cacheable-request": { + "node_modules/cacheable-request": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz", - "integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=", + "integrity": "sha512-vag0O2LKZ/najSoUwDbVlnlCFvhBE/7mGTY2B5FgCBDcRD+oVV1HYTOwM6JZfMg/hIcM6IwnTZ1uQQL5/X3xIQ==", "dev": true, - "requires": { + "dependencies": { "clone-response": "1.0.2", "get-stream": "3.0.0", "http-cache-semantics": "3.8.1", @@ -2074,695 +3129,842 @@ "lowercase-keys": "1.0.0", "normalize-url": "2.0.1", "responselike": "1.0.2" + } + }, + "node_modules/cacheable-request/node_modules/normalize-url": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", + "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", + "dev": true, + "dependencies": { + "prepend-http": "^2.0.0", + "query-string": "^5.0.1", + "sort-keys": "^2.0.0" }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cacheable-request/node_modules/prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/cacheable-request/node_modules/sort-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", + "integrity": "sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==", + "dev": true, "dependencies": { - "lowercase-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", - "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=", - "dev": true - }, - "normalize-url": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", - "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", - "dev": true, - "requires": { - "prepend-http": "^2.0.0", - "query-string": "^5.0.1", - "sort-keys": "^2.0.0" - } - }, - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true - }, - "sort-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", - "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", - "dev": true, - "requires": { - "is-plain-obj": "^1.0.0" - } - } + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=4" } }, - "call-me-maybe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", - "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", + "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==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", "dev": true }, - "caller-callsite": { + "node_modules/caller-callsite": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", "dev": true, - "requires": { + "dependencies": { "callsites": "^2.0.0" + }, + "engines": { + "node": ">=4" } }, - "caller-path": { + "node_modules/caller-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", "dev": true, - "requires": { + "dependencies": { "caller-callsite": "^2.0.0" + }, + "engines": { + "node": ">=4" } }, - "callsites": { + "node_modules/callsites": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", - "dev": true + "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", + "dev": true, + "engines": { + "node": ">=4" + } }, - "camelcase": { + "node_modules/camelcase": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true + "integrity": "sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "camelcase-keys": { + "node_modules/camelcase-keys": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "integrity": "sha512-bA/Z/DERHKqoEOrp+qeGKw1QlvEQkGZSc0XaY6VnTxZr+Kv1G5zFwttpjv8qxZ/sBPT4nthwZaAcsAZTJlSKXQ==", "dev": true, - "requires": { + "dependencies": { "camelcase": "^2.0.0", "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "caniuse-api": { + "node_modules/caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", "dev": true, - "requires": { + "dependencies": { "browserslist": "^4.0.0", "caniuse-lite": "^1.0.0", "lodash.memoize": "^4.1.2", "lodash.uniq": "^4.5.0" } }, - "caniuse-lite": { - "version": "1.0.30001116", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001116.tgz", - "integrity": "sha512-f2lcYnmAI5Mst9+g0nkMIznFGsArRmZ0qU+dnq8l91hymdc2J3SFbiPhOJEeDqC1vtE8nc1qNQyklzB8veJefQ==", - "dev": true + "node_modules/caniuse-lite": { + "version": "1.0.30001450", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001450.tgz", + "integrity": "sha512-qMBmvmQmFXaSxexkjjfMvD5rnDL0+m+dUMZKoDYsGG8iZN29RuYh9eRoMvKsT6uMAWlyUUGDEQGJJYjzCIO9ew==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] }, - "caseless": { + "node_modules/caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", "dev": true }, - "caw": { + "node_modules/caw": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/caw/-/caw-2.0.1.tgz", "integrity": "sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==", "dev": true, - "requires": { + "dependencies": { "get-proxy": "^2.0.0", "isurl": "^1.0.0-alpha5", "tunnel-agent": "^0.6.0", "url-to-options": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==", + "dev": true, + "dependencies": { + "traverse": ">=0.3.0 <0.4" + }, + "engines": { + "node": "*" } }, - "chalk": { + "node_modules/chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, - "requires": { + "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, - "dependencies": { - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "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 - }, - "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.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "engines": { + "node": ">=8" } }, - "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=", + "node_modules/cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", "dev": true, - "requires": { - "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" + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "dev": true, "dependencies": { - "css-select": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", - "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", - "dev": true, - "requires": { - "boolbase": "~1.0.0", - "css-what": "2.1", - "domutils": "1.5.1", - "nth-check": "~1.0.1" - } - }, - "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 - }, - "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, - "requires": { - "domelementtype": "^1.3.0", - "entities": "^1.1.1" - } - }, - "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", - "dev": true, - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "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" + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" } }, - "class-utils": { + "node_modules/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==", "dev": true, - "requires": { + "dependencies": { "arr-union": "^3.1.0", "define-property": "^0.2.5", "isobject": "^3.0.0", "static-extend": "^0.1.1" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, "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, - "requires": { - "is-descriptor": "^0.1.0" - } - } + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "classnames": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz", - "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==", - "dev": true + "node_modules/class-utils/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, - "requires": { - "restore-cursor": "^2.0.0" + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" } }, - "cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "node_modules/class-utils/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/classnames": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==", "dev": true }, - "clipboard": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz", - "integrity": "sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==", + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", "dev": true, - "optional": true, - "requires": { - "good-listener": "^1.2.2", - "select": "^1.1.2", - "tiny-emitter": "^2.0.0" + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "clone-response": { + "node_modules/clone-response": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==", "dev": true, - "requires": { + "dependencies": { "mimic-response": "^1.0.0" } }, - "coa": { + "node_modules/coa": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", "dev": true, - "requires": { + "dependencies": { "@types/q": "^1.5.1", "chalk": "^2.4.1", "q": "^1.1.2" }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/coa/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "dependencies": { - "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" - } - }, - "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 - } + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/coa/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/coa/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/coa/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/coa/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/coa/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==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/coa/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==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "coffee-script": { + "node_modules/coffee-script": { "version": "1.12.7", "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==", - "dev": true + "deprecated": "CoffeeScript on NPM has moved to \"coffeescript\" (no hyphen)", + "dev": true, + "bin": { + "cake": "bin/cake", + "coffee": "bin/coffee" + }, + "engines": { + "node": ">=0.8.0" + } }, - "collection-visit": { + "node_modules/collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", "dev": true, - "requires": { + "dependencies": { "map-visit": "^1.0.0", "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "color": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", - "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", + "node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", "dev": true, - "requires": { - "color-convert": "^1.9.1", - "color-string": "^1.5.2" + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" } }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "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, - "requires": { - "color-name": "1.1.3" + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "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 }, - "color-string": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", - "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "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==", "dev": true, - "requires": { + "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, - "colorette": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", - "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", + "node_modules/color/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "combined-stream": { + "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==", "dev": true, - "requires": { + "dependencies": { "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" } }, - "commander": { + "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 + "dev": true, + "engines": { + "node": ">= 6" + } }, - "commondir": { + "node_modules/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 }, - "component-emitter": { + "node_modules/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 }, - "concat-map": { + "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "concat-stream": { + "node_modules/concat-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, - "requires": { + "engines": [ + "node >= 0.8" + ], + "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^2.2.2", "typedarray": "^0.0.6" } }, - "concat-with-sourcemaps": { + "node_modules/concat-with-sourcemaps": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz", "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==", "dev": true, - "requires": { - "source-map": "^0.6.1" - }, "dependencies": { - "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 - } + "source-map": "^0.6.1" } }, - "config-chain": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", - "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", + "node_modules/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": { + "dependencies": { "ini": "^1.3.4", "proto-list": "~1.2.1" } }, - "console-stream": { + "node_modules/console-stream": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/console-stream/-/console-stream-0.1.1.tgz", - "integrity": "sha1-oJX+B7IEZZVfL6/Si11yvM2UnUQ=", + "integrity": "sha512-QC/8l9e6ofi6nqZ5PawlDgzmMw3OxIXtvolBzap/F4UDBJlDaZRSNbL/lb41C29FcbSJncBFlJFj2WJoNyZRfQ==", "dev": true }, - "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "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==", "dev": true, - "requires": { - "safe-buffer": "5.1.2" + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" } }, - "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==", - "dev": true + "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==", + "dev": true, + "engines": { + "node": ">= 0.6" + } }, - "continuable-cache": { + "node_modules/continuable-cache": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz", - "integrity": "sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=", + "integrity": "sha512-TF30kpKhTH8AGCG3dut0rdd/19B7Z+qCnrMoBLpyQu/2drZdNrrpcjPEoJeSVsQM+8KmWG5O56oPDjSSUsuTyA==", "dev": true }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "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==", "dev": true, - "requires": { - "safe-buffer": "~5.1.1" + "engines": { + "node": ">= 0.6" } }, - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", - "dev": true - }, - "cookie-signature": { + "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "dev": true }, - "copy-descriptor": { + "node_modules/copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true + "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true + "node_modules/core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", + "dev": true, + "hasInstallScript": true }, - "core-js-compat": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz", - "integrity": "sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==", + "node_modules/core-js-compat": { + "version": "3.27.2", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.27.2.tgz", + "integrity": "sha512-welaYuF7ZtbYKGrIy7y3eb40d37rG1FvzEOfe7hSLd2iD6duMDqUhRfSvCGyC46HhR6Y8JXXdZ2lnRUMkPBpvg==", "dev": true, - "requires": { - "browserslist": "^4.8.5", - "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.21.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" } }, - "core-util-is": { + "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", "dev": true }, - "cosmiconfig": { + "node_modules/cosmiconfig": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", "dev": true, - "requires": { + "dependencies": { "import-fresh": "^2.0.0", "is-directory": "^0.3.1", "js-yaml": "^3.13.1", "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" } }, - "cross-spawn": { + "node_modules/cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", "dev": true, - "requires": { + "dependencies": { "lru-cache": "^4.0.1", "shebang-command": "^1.2.0", "which": "^1.2.9" } }, - "crowdin-cli": { + "node_modules/cross-spawn/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/cross-spawn/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==", + "dev": true + }, + "node_modules/crowdin-cli": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/crowdin-cli/-/crowdin-cli-0.3.0.tgz", - "integrity": "sha1-6smYmm/n/qrzMJA5evwYfGe0YZE=", + "integrity": "sha512-s1vSRqWalCqd+vW7nF4oZo1a2pMpEgwIiwVlPRD0HmGY3HjJwQKXqZ26NpX5qCDVN8UdEsScy+2jle0PPQBmAg==", "dev": true, - "requires": { + "dependencies": { "request": "^2.53.0", "yamljs": "^0.2.1", "yargs": "^2.3.0" + }, + "bin": { + "crowdin-cli": "bin/crowdin-cli" } }, - "css-color-names": { + "node_modules/css-color-names": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", - "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", - "dev": true + "integrity": "sha512-zj5D7X1U2h2zsXOAM8EyUREBnnts6H+Jm+d1M2DbiQQcUtnqgQsMrdo8JW9R80YFUmIdBZeMu5wvYM7hcgWP/Q==", + "dev": true, + "engines": { + "node": "*" + } }, - "css-declaration-sorter": { + "node_modules/css-declaration-sorter": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", "dev": true, - "requires": { + "dependencies": { "postcss": "^7.0.1", "timsort": "^0.3.0" + }, + "engines": { + "node": ">4" } }, - "css-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", - "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", "dev": true, - "requires": { + "dependencies": { "boolbase": "^1.0.0", - "css-what": "^3.2.1", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" } }, - "css-select-base-adapter": { + "node_modules/css-select-base-adapter": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", "dev": true }, - "css-tree": { + "node_modules/css-tree": { "version": "1.0.0-alpha.37", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", "dev": true, - "requires": { + "dependencies": { "mdn-data": "2.0.4", "source-map": "^0.6.1" }, - "dependencies": { - "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": ">=8.0.0" } }, - "css-what": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.3.0.tgz", - "integrity": "sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg==", - "dev": true + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } }, - "cssesc": { + "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } }, - "cssnano": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz", - "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==", + "node_modules/cssnano": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz", + "integrity": "sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==", "dev": true, - "requires": { + "dependencies": { "cosmiconfig": "^5.0.0", - "cssnano-preset-default": "^4.0.7", + "cssnano-preset-default": "^4.0.8", "is-resolvable": "^1.0.0", "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "cssnano-preset-default": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz", - "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==", + "node_modules/cssnano-preset-default": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz", + "integrity": "sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==", "dev": true, - "requires": { + "dependencies": { "css-declaration-sorter": "^4.0.1", "cssnano-util-raw-cache": "^4.0.1", "postcss": "^7.0.0", @@ -2791,115 +3993,148 @@ "postcss-ordered-values": "^4.1.2", "postcss-reduce-initial": "^4.0.3", "postcss-reduce-transforms": "^4.0.2", - "postcss-svgo": "^4.0.2", + "postcss-svgo": "^4.0.3", "postcss-unique-selectors": "^4.0.1" + }, + "engines": { + "node": ">=6.9.0" } }, - "cssnano-util-get-arguments": { + "node_modules/cssnano-util-get-arguments": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", - "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=", - "dev": true + "integrity": "sha512-6RIcwmV3/cBMG8Aj5gucQRsJb4vv4I4rn6YjPbVWd5+Pn/fuG+YseGvXGk00XLkoZkaj31QOD7vMUpNPC4FIuw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, - "cssnano-util-get-match": { + "node_modules/cssnano-util-get-match": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", - "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=", - "dev": true + "integrity": "sha512-JPMZ1TSMRUPVIqEalIBNoBtAYbi8okvcFns4O0YIhcdGebeYZK7dMyHJiQ6GqNBA9kE0Hym4Aqym5rPdsV/4Cw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, - "cssnano-util-raw-cache": { + "node_modules/cssnano-util-raw-cache": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", "dev": true, - "requires": { + "dependencies": { "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "cssnano-util-same-parent": { + "node_modules/cssnano-util-same-parent": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", - "dev": true - }, - "csso": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.3.tgz", - "integrity": "sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ==", - "dev": true, - "requires": { - "css-tree": "1.0.0-alpha.39" - }, - "dependencies": { - "css-tree": { - "version": "1.0.0-alpha.39", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.39.tgz", - "integrity": "sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==", - "dev": true, - "requires": { - "mdn-data": "2.0.6", - "source-map": "^0.6.1" - } - }, - "mdn-data": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz", - "integrity": "sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==", - "dev": true - }, - "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 - } - } - }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", "dev": true, - "requires": { - "array-find-index": "^1.0.1" + "engines": { + "node": ">=6.9.0" } }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "node_modules/csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", "dev": true, - "requires": { - "assert-plus": "^1.0.0" + "dependencies": { + "css-tree": "^1.1.2" + }, + "engines": { + "node": ">=8.0.0" } }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "node_modules/csso/node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", "dev": true, - "requires": { - "ms": "^2.1.1" + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "dev": true + }, + "node_modules/currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==", + "dev": true, + "dependencies": { + "array-find-index": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "decamelize": { + "node_modules/decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "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 + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "dev": true, + "engines": { + "node": ">=0.10" + } }, - "decompress": { + "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, - "requires": { + "dependencies": { "decompress-tar": "^4.0.0", "decompress-tarbz2": "^4.0.0", "decompress-targz": "^4.0.0", @@ -2909,275 +4144,307 @@ "pify": "^2.3.0", "strip-dirs": "^2.0.0" }, - "dependencies": { - "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" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } + "engines": { + "node": ">=4" } }, - "decompress-response": { + "node_modules/decompress-response": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", "dev": true, - "requires": { + "dependencies": { "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" } }, - "decompress-tar": { + "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, - "requires": { + "dependencies": { "file-type": "^5.2.0", "is-stream": "^1.1.0", "tar-stream": "^1.5.2" }, - "dependencies": { - "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 - } + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tar/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" } }, - "decompress-tarbz2": { + "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, - "requires": { + "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" }, - "dependencies": { - "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/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" } }, - "decompress-targz": { + "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, - "requires": { + "dependencies": { "decompress-tar": "^4.1.1", "file-type": "^5.2.0", "is-stream": "^1.1.0" }, - "dependencies": { - "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 - } + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-targz/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" } }, - "decompress-unzip": { + "node_modules/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": { + "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": { - "file-type": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", - "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=", - "dev": true, - "requires": { - "object-assign": "^4.0.1", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } + "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" } }, - "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=", + "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/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==", "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==", + "node_modules/define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", "dev": true, - "requires": { - "object-keys": "^1.0.12" + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "define-property": { + "node_modules/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, - "requires": { + "dependencies": { "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, - "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, - "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, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } + "engines": { + "node": ">=0.10.0" } }, - "delayed-stream": { + "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "delegate": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", - "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true, - "optional": true + "engines": { + "node": ">=0.4.0" + } }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "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==", + "dev": true, + "engines": { + "node": ">= 0.8" + } }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } }, - "detect-port-alt": { + "node_modules/detect-port-alt": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", "dev": true, - "requires": { + "dependencies": { "address": "^1.0.1", "debug": "^2.6.0" }, + "bin": { + "detect": "bin/detect-port", + "detect-port": "bin/detect-port" + }, + "engines": { + "node": ">= 4.2.1" + } + }, + "node_modules/detect-port-alt/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": { - "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" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } + "ms": "2.0.0" } }, - "diacritics-map": { + "node_modules/detect-port-alt/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/diacritics-map": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/diacritics-map/-/diacritics-map-0.1.0.tgz", - "integrity": "sha1-bfwP+dAQAKLt8oZTccrDFulJd68=", - "dev": true + "integrity": "sha512-3omnDTYrGigU0i4cJjvaKwD52B8aoqyX/NEIkukFFkogBemsIbhSa1O414fpTp5nuszJG6lvQ5vBvDVNCbSsaQ==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } }, - "dir-glob": { + "node_modules/dir-glob": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz", "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==", "dev": true, - "requires": { + "dependencies": { "arrify": "^1.0.1", "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "docusaurus": { - "version": "1.14.6", - "resolved": "https://registry.npmjs.org/docusaurus/-/docusaurus-1.14.6.tgz", - "integrity": "sha512-Hpo6xqYIHwazwuhXW25AKYv/os+dWoJ87qql/m1j1xp83h/BnfYV2l8PA8zLggF1wGUbJQbTx7GWo6QvD8z+4Q==", - "dev": true, - "requires": { - "@babel/core": "^7.9.0", - "@babel/plugin-proposal-class-properties": "^7.8.3", - "@babel/plugin-proposal-object-rest-spread": "^7.9.0", - "@babel/polyfill": "^7.8.7", - "@babel/preset-env": "^7.9.0", - "@babel/preset-react": "^7.9.4", - "@babel/register": "^7.9.0", - "@babel/traverse": "^7.9.0", - "@babel/types": "^7.9.0", + "node_modules/discontinuous-range": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz", + "integrity": "sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==", + "dev": true + }, + "node_modules/docusaurus": { + "version": "1.14.7", + "resolved": "https://registry.npmjs.org/docusaurus/-/docusaurus-1.14.7.tgz", + "integrity": "sha512-UWqar4ZX0lEcpLc5Tg+MwZ2jhF/1n1toCQRSeoxDON/D+E9ToLr+vTRFVMP/Tk84NXSVjZFRlrjWwM2pXzvLsQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/plugin-proposal-class-properties": "^7.12.1", + "@babel/plugin-proposal-object-rest-spread": "^7.12.1", + "@babel/polyfill": "^7.12.1", + "@babel/preset-env": "^7.12.1", + "@babel/preset-react": "^7.12.5", + "@babel/register": "^7.12.1", + "@babel/traverse": "^7.12.5", + "@babel/types": "^7.12.6", "autoprefixer": "^9.7.5", "babylon": "^6.18.0", "chalk": "^3.0.0", @@ -3185,12 +4452,14 @@ "commander": "^4.0.1", "crowdin-cli": "^0.3.0", "cssnano": "^4.1.10", + "enzyme": "^3.10.0", + "enzyme-adapter-react-16": "^1.15.1", "escape-string-regexp": "^2.0.0", "express": "^4.17.1", - "feed": "^4.0.0", - "fs-extra": "^8.1.0", + "feed": "^4.2.1", + "fs-extra": "^9.0.1", "gaze": "^1.1.3", - "github-slugger": "^1.2.1", + "github-slugger": "^1.3.0", "glob": "^7.1.6", "highlight.js": "^9.16.2", "imagemin": "^6.0.0", @@ -3198,14 +4467,14 @@ "imagemin-jpegtran": "^6.0.0", "imagemin-optipng": "^6.0.0", "imagemin-svgo": "^7.0.0", - "lodash": "^4.17.15", + "lodash": "^4.17.20", "markdown-toc": "^1.2.0", "mkdirp": "^0.5.1", - "portfinder": "^1.0.25", + "portfinder": "^1.0.28", "postcss": "^7.0.23", - "prismjs": "^1.17.1", + "prismjs": "^1.22.0", "react": "^16.8.4", - "react-dev-utils": "^9.1.0", + "react-dev-utils": "^11.0.1", "react-dom": "^16.8.4", "remarkable": "^2.0.0", "request": "^2.88.0", @@ -3215,66 +4484,90 @@ "tiny-lr": "^1.1.1", "tree-node-cli": "^1.2.5", "truncate-html": "^1.0.3" + }, + "bin": { + "docusaurus-build": "lib/build-files.js", + "docusaurus-examples": "lib/copy-examples.js", + "docusaurus-publish": "lib/publish-gh-pages.js", + "docusaurus-rename-version": "lib/rename-version.js", + "docusaurus-start": "lib/start-server.js", + "docusaurus-version": "lib/version.js", + "docusaurus-write-translations": "lib/write-translations.js" } }, - "dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==", - "dev": true - } + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "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/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, - "requires": { - "domelementtype": "1" + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" } }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "node_modules/domutils": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", + "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", "dev": true, - "requires": { - "dom-serializer": "0", - "domelementtype": "1" + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.1" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" } }, - "dot-prop": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", - "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", + "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, - "requires": { + "dependencies": { "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" } }, - "download": { + "node_modules/download": { "version": "6.2.5", "resolved": "https://registry.npmjs.org/download/-/download-6.2.5.tgz", "integrity": "sha512-DpO9K1sXAST8Cpzb7kmEhogJxymyVUd5qz/vCOSyvwtp2Klj2XcDt5YUuasgxka44SxF0q5RriKIwJmQHG2AuA==", "dev": true, - "requires": { + "dependencies": { "caw": "^2.0.0", "content-disposition": "^0.5.2", "decompress": "^4.0.0", @@ -3287,217 +4580,429 @@ "p-event": "^1.0.0", "pify": "^3.0.0" }, + "engines": { + "node": ">=4" + } + }, + "node_modules/download/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/download/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": { - "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 - }, - "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" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/download/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" } }, - "duplexer": { + "node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "dev": true }, - "duplexer3": { + "node_modules/duplexer2": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "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/duplexer3": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", + "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", "dev": true }, - "ecc-jsbn": { + "node_modules/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==", "dev": true, - "requires": { + "dependencies": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" } }, - "ee-first": { + "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.539", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.539.tgz", - "integrity": "sha512-rM0LWDIstdqfaRUADZetNrL6+zd/0NBmavbMEhBXgc2u/CC1d1GaDyN5hho29fFvBiOVFwrSWZkzmNcZnCEDog==", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "dev": true }, - "emoji-regex": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.1.1.tgz", - "integrity": "sha1-xs0OwbBkLio8Z6ETfvxeeW2k+I4=", + "node_modules/electron-to-chromium": { + "version": "1.4.285", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.285.tgz", + "integrity": "sha512-47o4PPgxfU1KMNejz+Dgaodf7YTcg48uOfV1oM6cs3adrl2+7R+dHkt3Jpxqo0LRCbGJEzTKMUt0RdvByb/leg==", "dev": true }, - "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", - "dev": true + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "engines": { + "node": ">= 4" + } }, - "encodeurl": { + "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } }, - "end-of-stream": { + "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==", "dev": true, - "requires": { + "dependencies": { "once": "^1.4.0" } }, - "entities": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", - "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", - "dev": true - }, - "error": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/error/-/error-7.2.1.tgz", - "integrity": "sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA==", + "node_modules/entities": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", + "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", "dev": true, - "requires": { - "string-template": "~0.2.1" + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "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==", + "node_modules/enzyme": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/enzyme/-/enzyme-3.11.0.tgz", + "integrity": "sha512-Dw8/Gs4vRjxY6/6i9wU0V+utmQO9kvh9XLnz3LIudviOnVYDEe2ec+0k+NQoMamn1VrjKgCUOWj5jG/5M5M0Qw==", "dev": true, - "requires": { - "is-arrayish": "^0.2.1" + "dependencies": { + "array.prototype.flat": "^1.2.3", + "cheerio": "^1.0.0-rc.3", + "enzyme-shallow-equal": "^1.0.1", + "function.prototype.name": "^1.1.2", + "has": "^1.0.3", + "html-element-map": "^1.2.0", + "is-boolean-object": "^1.0.1", + "is-callable": "^1.1.5", + "is-number-object": "^1.0.4", + "is-regex": "^1.0.5", + "is-string": "^1.0.5", + "is-subset": "^0.1.1", + "lodash.escape": "^4.0.1", + "lodash.isequal": "^4.5.0", + "object-inspect": "^1.7.0", + "object-is": "^1.0.2", + "object.assign": "^4.1.0", + "object.entries": "^1.1.1", + "object.values": "^1.1.1", + "raf": "^3.4.1", + "rst-selector-parser": "^2.2.3", + "string.prototype.trim": "^1.2.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "node_modules/enzyme-adapter-react-16": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.15.7.tgz", + "integrity": "sha512-LtjKgvlTc/H7adyQcj+aq0P0H07LDL480WQl1gU512IUyaDo/sbOaNDdZsJXYW2XaoPqrLLE9KbZS+X2z6BASw==", "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", + "dependencies": { + "enzyme-adapter-utils": "^1.14.1", + "enzyme-shallow-equal": "^1.0.5", "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" + "object.assign": "^4.1.4", + "object.values": "^1.1.5", + "prop-types": "^15.8.1", + "react-is": "^16.13.1", + "react-test-renderer": "^16.0.0-0", + "semver": "^5.7.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + }, + "peerDependencies": { + "enzyme": "^3.0.0", + "react": "^16.0.0-0", + "react-dom": "^16.0.0-0" } }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "node_modules/enzyme-adapter-react-16/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "bin": { + "semver": "bin/semver" } }, - "escalade": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.0.2.tgz", - "integrity": "sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ==", - "dev": true + "node_modules/enzyme-adapter-utils": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/enzyme-adapter-utils/-/enzyme-adapter-utils-1.14.1.tgz", + "integrity": "sha512-JZgMPF1QOI7IzBj24EZoDpaeG/p8Os7WeBZWTJydpsH7JRStc7jYbHE4CmNQaLqazaGFyLM8ALWA3IIZvxW3PQ==", + "dev": true, + "dependencies": { + "airbnb-prop-types": "^2.16.0", + "function.prototype.name": "^1.1.5", + "has": "^1.0.3", + "object.assign": "^4.1.4", + "object.fromentries": "^2.0.5", + "prop-types": "^15.8.1", + "semver": "^5.7.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + }, + "peerDependencies": { + "react": "0.13.x || 0.14.x || ^15.0.0-0 || ^16.0.0-0" + } }, - "escape-html": { - "version": "1.0.3", + "node_modules/enzyme-adapter-utils/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/enzyme-shallow-equal": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.5.tgz", + "integrity": "sha512-i6cwm7hN630JXenxxJFBKzgLC3hMTafFQXflvzHgPmDhOBhxUWDe8AeRv1qp2/uWJ2Y8z5yLWMzmAfkTOiOCZg==", + "dev": true, + "dependencies": { + "has": "^1.0.3", + "object-is": "^1.1.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/error": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/error/-/error-7.2.1.tgz", + "integrity": "sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA==", + "dev": true, + "dependencies": { + "string-template": "~0.2.1" + } + }, + "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/es-abstract": { + "version": "1.21.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.1.tgz", + "integrity": "sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.3", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.4", + "is-array-buffer": "^3.0.1", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.2", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", + "dev": true + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "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": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "dev": true }, - "escape-string-regexp": { + "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 + "dev": true, + "engines": { + "node": ">=8" + } }, - "esprima": { + "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 + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } }, - "esutils": { + "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "etag": { + "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true - }, - "eventsource": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", - "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, - "requires": { - "original": "^1.0.0" + "engines": { + "node": ">= 0.6" } }, - "exec-buffer": { + "node_modules/exec-buffer": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/exec-buffer/-/exec-buffer-3.2.0.tgz", "integrity": "sha512-wsiD+2Tp6BWHoVv3B+5Dcx6E7u5zky+hUwOHjuH2hKSLR3dvRmX8fk8UD8uqQixHs4Wk6eDmiegVrMPjKj7wpA==", "dev": true, - "requires": { + "dependencies": { "execa": "^0.7.0", "p-finally": "^1.0.0", "pify": "^3.0.0", "rimraf": "^2.5.4", "tempfile": "^2.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 - } + "engines": { + "node": ">=4" } }, - "execa": { + "node_modules/exec-buffer/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/execa": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "integrity": "sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==", "dev": true, - "requires": { + "dependencies": { "cross-spawn": "^5.0.1", "get-stream": "^3.0.0", "is-stream": "^1.1.0", @@ -3505,31 +5010,38 @@ "p-finally": "^1.0.0", "signal-exit": "^3.0.0", "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=4" } }, - "executable": { + "node_modules/executable": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", "dev": true, - "requires": { + "dependencies": { "pify": "^2.2.0" }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } + "engines": { + "node": ">=4" + } + }, + "node_modules/executable/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" } }, - "expand-brackets": { + "node_modules/expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", "dev": true, - "requires": { + "dependencies": { "debug": "^2.3.3", "define-property": "^0.2.5", "extend-shallow": "^2.0.1", @@ -3538,217 +5050,226 @@ "snapdragon": "^0.8.1", "to-regex": "^3.0.1" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/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": { - "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" - } - }, - "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, - "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, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } + "ms": "2.0.0" + } + }, + "node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" } }, - "expand-range": { + "node_modules/expand-brackets/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/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/expand-range": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "integrity": "sha512-AFASGfIlnIbkKPQwX1yHaDjFvh/1gyKJODme52V6IORh69uEYgZp0o9C+qsIGNVEiuuhQU0CSSl++Rlegg1qvA==", "dev": true, - "requires": { + "dependencies": { "fill-range": "^2.1.0" }, - "dependencies": { - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.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, - "requires": { - "is-buffer": "^1.1.5" - } - } + "engines": { + "node": ">=0.10.0" } }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "dev": true, - "requires": { - "accepts": "~1.3.7", + "dependencies": { + "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.4.0", + "cookie": "0.5.0", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "~1.1.2", + "depd": "2.0.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "~1.1.2", + "finalhandler": "1.2.0", "fresh": "0.5.2", + "http-errors": "2.0.0", "merge-descriptors": "1.0.1", "methods": "~1.1.2", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", + "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/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": { - "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" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true - } + "ms": "2.0.0" } }, - "ext-list": { + "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==", + "dev": true + }, + "node_modules/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": { + "dependencies": { "mime-db": "^1.28.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "ext-name": { + "node_modules/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, - "requires": { + "dependencies": { "ext-list": "^2.0.0", "sort-keys-length": "^1.0.0" + }, + "engines": { + "node": ">=4" } }, - "extend": { + "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "dev": 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, - "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" + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "extglob": { + "node_modules/extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, - "requires": { + "dependencies": { "array-unique": "^0.3.2", "define-property": "^1.0.0", "expand-brackets": "^2.1.4", @@ -3758,548 +5279,831 @@ "snapdragon": "^0.8.1", "to-regex": "^3.0.1" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, "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, - "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, - "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, - "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, - "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, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "extsprintf": { + "node_modules/extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, + "engines": [ + "node >=0.6.0" + ] }, - "fast-deep-equal": { + "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==", "dev": true }, - "fast-glob": { + "node_modules/fast-folder-size": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/fast-folder-size/-/fast-folder-size-1.6.1.tgz", + "integrity": "sha512-F3tRpfkAzb7TT2JNKaJUglyuRjRa+jelQD94s9OSqkfEeytLmupCqQiD+H2KoIXGtp4pB5m4zNmv5m2Ktcr+LA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "unzipper": "^0.10.11" + }, + "bin": { + "fast-folder-size": "cli.js" + } + }, + "node_modules/fast-glob": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", "dev": true, - "requires": { + "dependencies": { "@mrmlnc/readdir-enhanced": "^2.2.1", "@nodelib/fs.stat": "^1.1.2", "glob-parent": "^3.1.0", "is-glob": "^4.0.0", "merge2": "^1.2.3", "micromatch": "^3.1.10" + }, + "engines": { + "node": ">=4.0.0" } }, - "fast-json-stable-stringify": { + "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==", "dev": true }, - "faye-websocket": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", - "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", + "node_modules/fast-xml-parser": { + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-3.21.1.tgz", + "integrity": "sha512-FTFVjYoBOZTJekiUsawGsSYV9QL0A+zDYCRj7y34IO6Jg+2IMYEtQa+bbictpdpV8dHxXywqU7C0gRDEOFtBFg==", + "dev": true, + "dependencies": { + "strnum": "^1.0.4" + }, + "bin": { + "xml2js": "cli.js" + }, + "funding": { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha512-Xhj93RXbMSq8urNCUq4p9l0P6hnySJ/7YNRhYNug0bLOuii7pKO7xQFb5mx9xZXWCar88pLPb805PvUkwrLZpQ==", "dev": true, - "requires": { + "dependencies": { "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.4.0" } }, - "fd-slicer": { + "node_modules/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": { + "dependencies": { "pend": "~1.2.0" } }, - "feed": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.1.tgz", - "integrity": "sha512-l28KKcK1J/u3iq5dRDmmoB2p7dtBfACC2NqJh4dI2kFptxH0asfjmOfcxqh5Sv8suAlVa73gZJ4REY5RrafVvg==", + "node_modules/feed": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", + "integrity": "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==", "dev": true, - "requires": { + "dependencies": { "xml-js": "^1.6.11" + }, + "engines": { + "node": ">=0.4.0" } }, - "figures": { + "node_modules/figures": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "integrity": "sha512-UxKlfCRuCBxSXU4C6t9scbDyWZ4VlaFFdojKtzJuSkuOBQ5CNFum+zZXFwHjo+CxBC1t6zlYPgHIgFjL8ggoEQ==", "dev": true, - "requires": { + "dependencies": { "escape-string-regexp": "^1.0.5", "object-assign": "^4.1.0" }, - "dependencies": { - "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 - } + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" } }, - "file-type": { + "node_modules/file-type": { "version": "10.11.0", "resolved": "https://registry.npmjs.org/file-type/-/file-type-10.11.0.tgz", "integrity": "sha512-uzk64HRpUZyTGZtVuvrjP0FYxzQrBf4rojot6J65YMEbwBLB0CWm0CLojVpwpmFmxcE/lkvYICgfcGozbBq6rw==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "filename-reserved-regex": { + "node_modules/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=", - "dev": true + "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", + "dev": true, + "engines": { + "node": ">=4" + } }, - "filenamify": { + "node_modules/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": { + "dependencies": { "filename-reserved-regex": "^2.0.0", "strip-outer": "^1.0.0", "trim-repeated": "^1.0.0" + }, + "engines": { + "node": ">=4" } }, - "filesize": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz", - "integrity": "sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==", - "dev": true + "node_modules/filesize": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz", + "integrity": "sha512-LpCHtPQ3sFx67z+uh2HnSyWSLLu5Jxo21795uRDuar/EOuYWXib5EmPaGIBuSnRqH2IODiKA2k5re/K9OnN/Yg==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "node_modules/fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" + "dependencies": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fill-range/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", + "dev": true, "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, - "requires": { - "is-extendable": "^0.1.0" - } - } + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dev": true, - "requires": { + "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", - "statuses": "~1.5.0", + "statuses": "2.0.1", "unpipe": "~1.0.0" }, + "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==", + "dev": true, "dependencies": { - "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" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } + "ms": "2.0.0" } }, - "find-cache-dir": { + "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==", + "dev": true + }, + "node_modules/find-cache-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", "dev": true, - "requires": { + "dependencies": { "commondir": "^1.0.1", "make-dir": "^2.0.0", "pkg-dir": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "find-up": { + "node_modules/find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, - "requires": { + "dependencies": { "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "find-versions": { + "node_modules/find-versions": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz", "integrity": "sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==", "dev": true, - "requires": { + "dependencies": { "semver-regex": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" } }, - "for-in": { + "node_modules/for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "forever-agent": { + "node_modules/forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, + "engines": { + "node": "*" + } }, - "fork-ts-checker-webpack-plugin": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-1.5.0.tgz", - "integrity": "sha512-zEhg7Hz+KhZlBhILYpXy+Beu96gwvkROWJiTXOCyOOMMrdBIRPvsBpBqgTI4jfJGrJXcqGwJR8zsBGDmzY0jsA==", + "node_modules/fork-ts-checker-webpack-plugin": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-4.1.6.tgz", + "integrity": "sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw==", "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", + "dependencies": { + "@babel/code-frame": "^7.5.5", "chalk": "^2.4.1", - "chokidar": "^2.0.4", "micromatch": "^3.1.10", "minimatch": "^3.0.4", "semver": "^5.6.0", "tapable": "^1.0.0", "worker-rpc": "^0.1.0" }, + "engines": { + "node": ">=6.11.5", + "yarn": ">=1.0.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "dependencies": { - "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" - } - }, - "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 - } + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" } }, - "form-data": { + "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/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==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/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/fork-ts-checker-webpack-plugin/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==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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==", "dev": true, - "requires": { + "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" } }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", - "dev": true + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } }, - "fragment-cache": { + "node_modules/fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", "dev": true, - "requires": { + "dependencies": { "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" } }, - "fresh": { + "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } }, - "from2": { + "node_modules/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": { + "dependencies": { "inherits": "^2.0.1", "readable-stream": "^2.0.0" } }, - "fs-constants": { + "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 }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "node_modules/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": { + "dependencies": { + "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" + }, + "engines": { + "node": ">=10" } }, - "fs.realpath": { + "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, - "function-bind": { + "node_modules/fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "gaze": { + "node_modules/function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gaze": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", "dev": true, - "requires": { + "dependencies": { "globule": "^1.0.0" + }, + "engines": { + "node": ">= 4.0.0" } }, - "gensync": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", - "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", - "dev": true + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "get-proxy": { + "node_modules/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": { + "dependencies": { "npm-conf": "^1.1.0" + }, + "engines": { + "node": ">=4" } }, - "get-stdin": { + "node_modules/get-stdin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true + "integrity": "sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "get-stream": { + "node_modules/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 + "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "get-value": { + "node_modules/get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "getpass": { + "node_modules/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==", "dev": true, - "requires": { + "dependencies": { "assert-plus": "^1.0.0" } }, - "gifsicle": { + "node_modules/gifsicle": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/gifsicle/-/gifsicle-4.0.1.tgz", "integrity": "sha512-A/kiCLfDdV+ERV/UB+2O41mifd+RxH8jlRG8DMxZO84Bma/Fw0htqZ+hY2iaalLRNyUu7tYZQslqUBJxBggxbg==", "dev": true, - "requires": { + "hasInstallScript": true, + "dependencies": { "bin-build": "^3.0.0", "bin-wrapper": "^4.0.0", "execa": "^1.0.0", "logalot": "^2.0.0" }, + "bin": { + "gifsicle": "cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/gifsicle/node_modules/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, "dependencies": { - "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, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - } + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" } }, - "github-slugger": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.3.0.tgz", - "integrity": "sha512-gwJScWVNhFYSRDvURk/8yhcFBee6aFjye2a7Lhb2bUyRulpIoek9p0I9Kt7PT67d/nUlZbFu8L9RLiA0woQN8Q==", + "node_modules/gifsicle/node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/gifsicle/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/gifsicle/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true, - "requires": { - "emoji-regex": ">=6.0.0 <=6.1.1" + "bin": { + "semver": "bin/semver" } }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "node_modules/github-slugger": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", + "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==", + "dev": true + }, + "node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", "dev": true, - "requires": { + "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" } }, - "glob-parent": { + "node_modules/glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", "dev": true, - "requires": { + "dependencies": { "is-glob": "^3.1.0", "path-dirname": "^1.0.0" - }, + } + }, + "node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "dev": true, "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, - "requires": { - "is-extglob": "^2.1.0" - } - } + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "glob-to-regexp": { + "node_modules/glob-to-regexp": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", + "integrity": "sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==", "dev": true }, - "global-modules": { + "node_modules/global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", "dev": true, - "requires": { + "dependencies": { "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "global-prefix": { + "node_modules/global-prefix": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", "dev": true, - "requires": { + "dependencies": { "ini": "^1.3.5", "kind-of": "^6.0.2", "which": "^1.3.1" + }, + "engines": { + "node": ">=6" } }, - "globals": { + "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "globby": { + "node_modules/globby": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.2.tgz", "integrity": "sha512-yTzMmKygLp8RUpG1Ymu2VXPSJQZjNAZPD4ywgYEaG7e4tBJeUQBO8OpXrf1RCNcEs5alsoJYPAMiIHP0cmeC7w==", "dev": true, - "requires": { + "dependencies": { "array-union": "^1.0.1", "dir-glob": "2.0.0", "fast-glob": "^2.0.2", @@ -4308,42 +6112,51 @@ "pify": "^3.0.0", "slash": "^1.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 - } + "engines": { + "node": ">=4" } }, - "globule": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz", - "integrity": "sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==", + "node_modules/globby/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/globule": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.4.tgz", + "integrity": "sha512-OPTIfhMBh7JbBYDpa5b+Q5ptmMWKwcNcFSR/0c6t8V4f3ZAVBEsKNY37QdVqmLRYSMhOUGYrY0QhSoEpzGr/Eg==", "dev": true, - "requires": { + "dependencies": { "glob": "~7.1.1", - "lodash": "~4.17.10", + "lodash": "^4.17.21", "minimatch": "~3.0.2" + }, + "engines": { + "node": ">= 0.10" } }, - "good-listener": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", - "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, - "optional": true, - "requires": { - "delegate": "^3.1.2" + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "got": { + "node_modules/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": { + "dependencies": { "decompress-response": "^3.2.0", "duplexer3": "^0.1.4", "get-stream": "^3.0.0", @@ -4358,292 +6171,421 @@ "timed-out": "^4.0.0", "url-parse-lax": "^1.0.0", "url-to-options": "^1.0.1" + }, + "engines": { + "node": ">=4" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "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 }, - "gray-matter": { + "node_modules/gray-matter": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-2.1.1.tgz", - "integrity": "sha1-MELZrewqHe1qdwep7SOA+KF6Qw4=", + "integrity": "sha512-vbmvP1Fe/fxuT2QuLVcqb2BfK7upGhhbLIt9/owWEvPYrZZEkelLcq2HqzxosV+PQ67dUFLaAeNpH7C4hhICAA==", "dev": true, - "requires": { + "dependencies": { "ansi-red": "^0.1.1", "coffee-script": "^1.12.4", "extend-shallow": "^2.0.1", "js-yaml": "^3.8.1", "toml": "^2.3.2" }, - "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, - "requires": { - "is-extendable": "^0.1.0" - } - } + "engines": { + "node": ">=0.10.0" } }, - "gulp-header": { + "node_modules/gulp-header": { "version": "1.8.12", "resolved": "https://registry.npmjs.org/gulp-header/-/gulp-header-1.8.12.tgz", "integrity": "sha512-lh9HLdb53sC7XIZOYzTXM4lFuXElv3EVkSDhsd7DoJBj7hm+Ni7D3qYbb+Rr8DuM8nRanBvkVO9d7askreXGnQ==", + "deprecated": "Removed event-stream from gulp-header", "dev": true, - "requires": { + "dependencies": { "concat-with-sourcemaps": "*", "lodash.template": "^4.4.0", "through2": "^2.0.0" } }, - "gzip-size": { + "node_modules/gzip-size": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", "dev": true, - "requires": { + "dependencies": { "duplexer": "^0.1.1", "pify": "^4.0.1" + }, + "engines": { + "node": ">=6" } }, - "har-schema": { + "node_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "dev": true, + "engines": { + "node": ">=4" + } }, - "har-validator": { + "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", "dev": true, - "requires": { + "dependencies": { "ajv": "^6.12.3", "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" } }, - "has": { + "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, - "requires": { + "dependencies": { "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" } }, - "has-ansi": { + "node_modules/has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", "dev": true, - "requires": { + "dependencies": { "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "node_modules/has-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "has-symbol-support-x": { + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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 + "dev": true, + "engines": { + "node": "*" + } }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true + "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==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "has-to-string-tag-x": { + "node_modules/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": { + "dependencies": { "has-symbol-support-x": "^1.4.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "has-value": { + "node_modules/has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", "dev": true, - "requires": { + "dependencies": { "get-value": "^2.0.6", "has-values": "^1.0.0", "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "has-values": { + "node_modules/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=", + "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", "dev": true, - "requires": { + "dependencies": { "is-number": "^3.0.0", "kind-of": "^4.0.0" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, "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, - "requires": { - "is-buffer": "^1.1.5" - } - } + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" } }, - "hex-color-regex": { + "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hex-color-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", "dev": true }, - "highlight.js": { - "version": "9.18.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.3.tgz", - "integrity": "sha512-zBZAmhSupHIl5sITeMqIJnYCDfAEc3Gdkqj65wC1lpI468MMQeeQkhcIAvk+RylAkxrCcI9xy9piHiXeQ1BdzQ==", - "dev": true + "node_modules/highlight.js": { + "version": "9.18.5", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.5.tgz", + "integrity": "sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA==", + "deprecated": "Support has ended for 9.x series. Upgrade to @latest", + "dev": true, + "hasInstallScript": true, + "engines": { + "node": "*" + } }, - "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "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 }, - "hsl-regex": { + "node_modules/hsl-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", - "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=", + "integrity": "sha512-M5ezZw4LzXbBKMruP+BNANf0k+19hDQMgpzBIYnya//Al+fjNct9Wf3b1WedLqdEs2hKBvxq/jh+DsHJLj0F9A==", "dev": true }, - "hsla-regex": { + "node_modules/hsla-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", - "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=", - "dev": true - }, - "html-comment-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", - "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==", + "integrity": "sha512-7Wn5GMLuHBjZCb2bTmnDOycho0p/7UVaAeqXZGbHrBCl6Yd/xDhQJAXe6Ga9AXJH2I5zY1dEdYw2u1UptnSBJA==", "dev": true }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "node_modules/html-element-map": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/html-element-map/-/html-element-map-1.3.1.tgz", + "integrity": "sha512-6XMlxrAFX4UEEGxctfFnmrFaaZFNf9i5fNuV5wZ3WWQ4FVaNP1aX1LkX9j2mfEx1NpjeE/rL3nmgEn23GdFmrg==", "dev": true, - "requires": { - "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" - }, "dependencies": { - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "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" - } + "array.prototype.filter": "^1.0.0", + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/htmlparser2": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", + "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "entities": "^4.3.0" } }, - "http-cache-semantics": { + "node_modules/http-cache-semantics": { "version": "3.8.1", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", "dev": true }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "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==", + "dev": true, + "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" } }, - "http-parser-js": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.2.tgz", - "integrity": "sha512-opCO9ASqg5Wy2FNo7A0sxy71yGbbkJJXLdgMK04Tcypw9jr2MgWbyubb0+WdmDmGnFflO7fRbqbaihh/ENDlRQ==", + "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==", "dev": true }, - "http-signature": { + "node_modules/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==", "dev": true, - "requires": { + "dependencies": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" } }, - "iconv-lite": { + "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==", "dev": true, - "requires": { + "dependencies": { "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" } }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "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" + } + ] }, - "ignore": { + "node_modules/ignore": { "version": "3.3.10", "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", "dev": true }, - "imagemin": { + "node_modules/imagemin": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/imagemin/-/imagemin-6.1.0.tgz", "integrity": "sha512-8ryJBL1CN5uSHpiBMX0rJw79C9F9aJqMnjGnrd/1CafegpNuA81RBAAru/jQQEOWlOJJlpRnlcVFF6wq+Ist0A==", "dev": true, - "requires": { + "dependencies": { "file-type": "^10.7.0", "globby": "^8.0.1", "make-dir": "^1.0.0", @@ -4651,299 +6593,308 @@ "pify": "^4.0.1", "replace-ext": "^1.0.0" }, - "dependencies": { - "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" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - } + "engines": { + "node": ">=6" } }, - "imagemin-gifsicle": { + "node_modules/imagemin-gifsicle": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/imagemin-gifsicle/-/imagemin-gifsicle-6.0.1.tgz", "integrity": "sha512-kuu47c6iKDQ6R9J10xCwL0lgs0+sMz3LRHqRcJ2CRBWdcNmo3T5hUaM8hSZfksptZXJLGKk8heSAvwtSdB1Fng==", "dev": true, - "requires": { + "dependencies": { "exec-buffer": "^3.0.0", "gifsicle": "^4.0.0", "is-gif": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "imagemin-jpegtran": { + "node_modules/imagemin-jpegtran": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/imagemin-jpegtran/-/imagemin-jpegtran-6.0.0.tgz", "integrity": "sha512-Ih+NgThzqYfEWv9t58EItncaaXIHR0u9RuhKa8CtVBlMBvY0dCIxgQJQCfwImA4AV1PMfmUKlkyIHJjb7V4z1g==", "dev": true, - "requires": { + "dependencies": { "exec-buffer": "^3.0.0", "is-jpg": "^2.0.0", "jpegtran-bin": "^4.0.0" + }, + "engines": { + "node": ">=6" } }, - "imagemin-optipng": { + "node_modules/imagemin-optipng": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/imagemin-optipng/-/imagemin-optipng-6.0.0.tgz", "integrity": "sha512-FoD2sMXvmoNm/zKPOWdhKpWdFdF9qiJmKC17MxZJPH42VMAp17/QENI/lIuP7LCUnLVAloO3AUoTSNzfhpyd8A==", "dev": true, - "requires": { + "dependencies": { "exec-buffer": "^3.0.0", "is-png": "^1.0.0", "optipng-bin": "^5.0.0" + }, + "engines": { + "node": ">=6" } }, - "imagemin-svgo": { + "node_modules/imagemin-svgo": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/imagemin-svgo/-/imagemin-svgo-7.1.0.tgz", "integrity": "sha512-0JlIZNWP0Luasn1HT82uB9nU9aa+vUj6kpT+MjPW11LbprXC+iC4HDwn1r4Q2/91qj4iy9tRZNsFySMlEpLdpg==", "dev": true, - "requires": { + "dependencies": { "is-svg": "^4.2.1", "svgo": "^1.3.2" }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sindresorhus/imagemin-svgo?sponsor=1" + } + }, + "node_modules/imagemin/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": { - "is-svg": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-4.2.1.tgz", - "integrity": "sha512-PHx3ANecKsKNl5y5+Jvt53Y4J7MfMpbNZkv384QNiswMKAWIbvcqbPz+sYbFKJI8Xv3be01GSFniPmoaP+Ai5A==", - "dev": true, - "requires": { - "html-comment-regex": "^1.1.2" - } - } + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "immer": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/immer/-/immer-1.10.0.tgz", - "integrity": "sha512-O3sR1/opvCDGLEVcvrGTMtLac8GJ5IwZC4puPrLuRj3l7ICKvkmA0vGuU9OW8mV9WIBRnaxp5GJh9IEAaNOoYg==", - "dev": true + "node_modules/imagemin/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" + } }, - "import-fresh": { + "node_modules/immer": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/immer/-/immer-8.0.1.tgz", + "integrity": "sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/import-fresh": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", "dev": true, - "requires": { + "dependencies": { "caller-path": "^2.0.0", "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "import-lazy": { + "node_modules/import-lazy": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-3.1.0.tgz", "integrity": "sha512-8/gvXvX2JMn0F+CDlSC4l6kOmVaLOO3XLkksI7CI3Ud95KDYJuYur2b9P/PUt/i/pDAMd/DulQsNbbbmRRsDIQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "indent-string": { + "node_modules/indent-string": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "integrity": "sha512-aqwDFWSgSgfRaEwao5lg5KEcVd/2a+D1rvoG7NdilmYz0NwRk6StWpWdz/Hpk34MKPpx7s8XxUqimfcQK6gGlg==", "dev": true, - "requires": { + "dependencies": { "repeating": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "indexes-of": { + "node_modules/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": { + "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, - "requires": { + "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, - "inherits": { + "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true - }, - "inquirer": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.0.tgz", - "integrity": "sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA==", - "dev": true, - "requires": { - "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - }, - "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 - }, - "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" - } - }, - "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 - }, - "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" - } - }, - "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" - } - } + "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/internal-slot": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.4.tgz", + "integrity": "sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" } }, - "interpret": { + "node_modules/interpret": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.10" + } }, - "into-stream": { + "node_modules/into-stream": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", - "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=", + "integrity": "sha512-TcdjPibTksa1NQximqep2r17ISRiNE9fwlfbg3F8ANdvP5/yrFTew86VcO//jk4QTaMlbjypPBq76HN2zaKfZQ==", "dev": true, - "requires": { + "dependencies": { "from2": "^2.1.1", "p-is-promise": "^1.1.0" + }, + "engines": { + "node": ">=4" } }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "node_modules/ip-regex": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", + "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==", "dev": true, - "requires": { - "loose-envify": "^1.0.0" + "engines": { + "node": ">=8" } }, - "ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", - "dev": true - }, - "ipaddr.js": { + "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==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.10" + } }, - "is-absolute-url": { + "node_modules/is-absolute-url": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", - "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", - "dev": true + "integrity": "sha512-vOx7VprsKyllwjSkLV79NIhpyLfr3jAp7VaTCMXOJHu4m0Ew1CZ2fcjASwmV1jI3BWuWHB013M48eyeldk9gYg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "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=", + "node_modules/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, - "requires": { - "kind-of": "^3.0.2" + "dependencies": { + "kind-of": "^6.0.0" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.1.tgz", + "integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==", + "dev": true, "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, - "requires": { - "is-buffer": "^1.1.5" - } - } + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-arrayish": { + "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, - "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=", + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, - "requires": { - "binary-extensions": "^1.0.0" + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-buffer": { + "node_modules/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 }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "is-color-stop": { + "node_modules/is-color-stop": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", - "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", + "integrity": "sha512-H1U8Vz0cfXNujrJzEcvvwMDW9Ra+biSYA3ThdQvAnMLJkEHQXn6bWzLkxHtVYJ+Sdbx0b6finn3jZiaVe7MAHA==", "dev": true, - "requires": { + "dependencies": { "css-color-names": "^0.0.4", "hex-color-regex": "^1.1.0", "hsl-regex": "^1.0.0", @@ -4952,782 +6903,1048 @@ "rgba-regex": "^1.0.0" } }, - "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=", + "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, - "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, - "requires": { - "is-buffer": "^1.1.5" - } - } + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true + "node_modules/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, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.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==", + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "dependencies": { + "has-tostringtag": "^1.0.0" }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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, "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 - } + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" } }, - "is-directory": { + "node_modules/is-directory": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", - "dev": true + "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "is-extendable": { + "node_modules/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 + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "is-extglob": { + "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "is-finite": { + "node_modules/is-finite": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", - "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=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "is-gif": { + "node_modules/is-gif": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-gif/-/is-gif-3.0.0.tgz", "integrity": "sha512-IqJ/jlbw5WJSNfwQ/lHEDXF8rxhRgF6ythk2oiEvhpG29F704eX9NO6TvPfMiq9DrbwgcEDnETYNcZDPewQoVw==", "dev": true, - "requires": { + "dependencies": { "file-type": "^10.4.0" + }, + "engines": { + "node": ">=6" } }, - "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==", + "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==", "dev": true, - "requires": { + "dependencies": { "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "is-jpg": { + "node_modules/is-jpg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-jpg/-/is-jpg-2.0.0.tgz", - "integrity": "sha1-LhmX+m6RZuqsAkLarkQ0A+TvHZc=", - "dev": true + "integrity": "sha512-ODlO0ruzhkzD3sdynIainVP5eoOFNN85rxA1+cwwnPe4dKyX0r5+hxNO5XpCrxlHcmb9vkOit9mhRD2JVuimHg==", + "dev": true, + "engines": { + "node": ">=6" + } }, - "is-natural-number": { + "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": "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=", + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "dev": true, - "requires": { - "kind-of": "^3.0.2" + "engines": { + "node": ">= 0.4" }, - "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, - "requires": { - "is-buffer": "^1.1.5" - } - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-obj": { + "node_modules/is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha512-QUzH43Gfb9+5yckcrSA0VBDwEtDUchrk4F6tfJZQuNzDJbEDB9cZNzSfXGQ1jqmdDY/kl41lUOWM9syA8z8jlg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.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 + "dev": true, + "engines": { + "node": ">=8" + } }, - "is-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", - "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=", - "dev": true + "node_modules/is-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", + "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "is-plain-obj": { + "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": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "is-plain-object": { + "node_modules/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, - "requires": { + "dependencies": { "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "is-png": { + "node_modules/is-png": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-png/-/is-png-1.1.0.tgz", - "integrity": "sha1-1XSxK/J1wDUEVVcLDltXqwYgd84=", - "dev": true + "integrity": "sha512-23Rmps8UEx3Bzqr0JqAtQo0tYP6sDfIfMt1rL9rzlla/zbteftI9LSJoqsIoGgL06sJboDGdVns4RTakAW/WTw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, - "requires": { - "has-symbols": "^1.0.1" + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-resolvable": { + "node_modules/is-resolvable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", "dev": true }, - "is-retry-allowed": { + "node_modules/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==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "is-root": { + "node_modules/is-root": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "is-stream": { + "node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-subset": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz", + "integrity": "sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw==", "dev": true }, - "is-svg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", - "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==", + "node_modules/is-svg": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-4.3.2.tgz", + "integrity": "sha512-mM90duy00JGMyjqIVHu9gNTjywdZV+8qNasX8cm/EEYZ53PHDgajvbBwNVvty5dwSAxLUD3p3bdo+7sR/UMrpw==", "dev": true, - "requires": { - "html-comment-regex": "^1.1.0" + "dependencies": { + "fast-xml-parser": "^3.19.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", + "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", "dev": true, - "requires": { - "has-symbols": "^1.0.1" + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-typedarray": { + "node_modules/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==", "dev": true }, - "is-url": { + "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 }, - "is-utf8": { + "node_modules/is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", "dev": true }, - "is-windows": { + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } }, - "is2": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is2/-/is2-2.0.1.tgz", - "integrity": "sha512-+WaJvnaA7aJySz2q/8sLjMb2Mw14KTplHmSwcSpZ/fWJPkUmqw3YTzSWbPJ7OAwRvdYTWF2Wg+yYJ1AdP5Z8CA==", + "node_modules/is2": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/is2/-/is2-2.0.9.tgz", + "integrity": "sha512-rZkHeBn9Zzq52sd9IUIV3a5mfwBY+o2HePMh0wkGBM4z4qjvy2GwVxQ6nNXSfw6MmVP6gf1QIlWjiOavhM3x5g==", "dev": true, - "requires": { + "dependencies": { "deep-is": "^0.1.3", - "ip-regex": "^2.1.0", - "is-url": "^1.2.2" + "ip-regex": "^4.1.0", + "is-url": "^1.2.4" + }, + "engines": { + "node": ">=v0.10.0" } }, - "isarray": { + "node_modules/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": { + "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "isobject": { + "node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "isstream": { + "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", "dev": true }, - "isurl": { + "node_modules/isurl": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", "dev": true, - "requires": { + "dependencies": { "has-to-string-tag-x": "^1.2.0", "is-object": "^1.0.1" + }, + "engines": { + "node": ">= 4" } }, - "jpegtran-bin": { + "node_modules/jpegtran-bin": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jpegtran-bin/-/jpegtran-bin-4.0.0.tgz", "integrity": "sha512-2cRl1ism+wJUoYAYFt6O/rLBfpXNWG2dUWbgcEkTt5WGMnqI46eEro8T4C5zGROxKRqyKpCBSdHPvt5UYCtxaQ==", "dev": true, - "requires": { + "hasInstallScript": true, + "dependencies": { "bin-build": "^3.0.0", "bin-wrapper": "^4.0.0", "logalot": "^2.0.0" + }, + "bin": { + "jpegtran": "cli.js" + }, + "engines": { + "node": ">=6" } }, - "js-tokens": { + "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==", "dev": true }, - "js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "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, - "requires": { + "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "jsbn": { + "node_modules/jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", "dev": true }, - "jsesc": { + "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } }, - "json-buffer": { + "node_modules/json-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", "dev": true }, - "json-parse-better-errors": { + "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 }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "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==", "dev": true }, - "json-schema-traverse": { + "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==", "dev": true }, - "json-stringify-safe": { + "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", "dev": true }, - "json3": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", - "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==", - "dev": true - }, - "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, - "requires": { - "minimist": "^1.2.5" + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" } }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "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, - "requires": { + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { "graceful-fs": "^4.1.6" } }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", "dev": true, - "requires": { + "dependencies": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", - "json-schema": "0.2.3", + "json-schema": "0.4.0", "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" } }, - "keyv": { + "node_modules/keyv": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz", "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==", "dev": true, - "requires": { + "dependencies": { "json-buffer": "3.0.0" } }, - "kind-of": { + "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 - }, - "lazy-cache": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz", - "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=", "dev": true, - "requires": { - "set-getter": "^0.1.0" + "engines": { + "node": ">=0.10.0" } }, - "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 + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } }, - "levenary": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", - "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", + "node_modules/lazy-cache": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz", + "integrity": "sha512-7vp2Acd2+Kz4XkzxGxaB1FWOi8KjWIWsgdfD5MCb86DWvlLqhRPM+d6Pro3iNEL5VT9mstz5hKAlcd+QR6H3aA==", "dev": true, - "requires": { - "leven": "^3.1.0" + "dependencies": { + "set-getter": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "list-item": { + "node_modules/list-item": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/list-item/-/list-item-1.1.1.tgz", - "integrity": "sha1-DGXQDih8tmPMs8s4Sad+iewmilY=", + "integrity": "sha512-S3D0WZ4J6hyM8o5SNKWaMYB1ALSacPZ2nHGEuCjmHZ+dc03gFeNZoNDcqfcnO4vDhTZmNrqrpYZCdXsRh22bzw==", "dev": true, - "requires": { + "dependencies": { "expand-range": "^1.8.1", "extend-shallow": "^2.0.1", "is-number": "^2.1.0", "repeat-string": "^1.5.2" }, - "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, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "engines": { + "node": ">=0.10.0" } }, - "livereload-js": { + "node_modules/listenercount": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", + "integrity": "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==", + "dev": true + }, + "node_modules/livereload-js": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz", "integrity": "sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw==", "dev": true }, - "load-json-file": { + "node_modules/load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", "dev": true, - "requires": { + "dependencies": { "graceful-fs": "^4.1.2", "parse-json": "^2.2.0", "pify": "^2.0.0", "pinkie-promise": "^2.0.0", "strip-bom": "^2.0.0" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-json-file/node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", + "dev": true, "dependencies": { - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "node_modules/load-json-file/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/loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", "dev": true, - "requires": { + "dependencies": { "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - } + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" } }, - "locate-path": { + "node_modules/locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, - "requires": { + "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "lodash._reinterpolate": { + "node_modules/lodash._reinterpolate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==", "dev": true }, - "lodash.assignin": { + "node_modules/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": { + "node_modules/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.chunk": { + "node_modules/lodash.chunk": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.chunk/-/lodash.chunk-4.2.0.tgz", - "integrity": "sha1-ZuXOH3btJ7QwPYxlEujRIW6BBrw=", + "integrity": "sha512-ZzydJKfUHJwHa+hF5X66zLFCBrWn5GeF28OHEr4WVWtNDXlQ/IjWKPBiikqKo2ne0+v6JgCgJ0GzJp8k8bHC7w==", "dev": true }, - "lodash.defaults": { + "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": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", + "dev": true + }, + "node_modules/lodash.escape": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-4.0.1.tgz", + "integrity": "sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw==", "dev": true }, - "lodash.filter": { + "node_modules/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": { + "node_modules/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 + }, + "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 }, - "lodash.foreach": { + "node_modules/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.map": { + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "dev": true + }, + "node_modules/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.memoize": { + "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", "dev": true }, - "lodash.merge": { + "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==", "dev": true }, - "lodash.padstart": { + "node_modules/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": { + "node_modules/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": { + "node_modules/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": { + "node_modules/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": { + "node_modules/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.sortby": { + "node_modules/lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", "dev": true }, - "lodash.template": { + "node_modules/lodash.template": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", "dev": true, - "requires": { + "dependencies": { "lodash._reinterpolate": "^3.0.0", "lodash.templatesettings": "^4.0.0" } }, - "lodash.templatesettings": { + "node_modules/lodash.templatesettings": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", "dev": true, - "requires": { + "dependencies": { "lodash._reinterpolate": "^3.0.0" } }, - "lodash.uniq": { + "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", "dev": true }, - "logalot": { + "node_modules/logalot": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/logalot/-/logalot-2.1.0.tgz", - "integrity": "sha1-X46MkNME7fElMJUaVVSruMXj9VI=", + "integrity": "sha512-Ah4CgdSRfeCJagxQhcVNMi9BfGYyEKLa6d7OA6xSbld/Hg3Cf2QiOa1mDpmG7Ve8LOH6DN3mdttzjQAvWTyVkw==", "dev": true, - "requires": { + "dependencies": { "figures": "^1.3.5", "squeak": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "longest": { + "node_modules/longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true + "integrity": "sha512-k+yt5n3l48JU4k8ftnKG6V7u32wyH2NfKzeMto9F/QRE0amxy/LayxwlvjjkZEIzqR+19IrtFO8p5kB9QaYUFg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "loose-envify": { + "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, - "requires": { + "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" } }, - "loud-rejection": { + "node_modules/loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "integrity": "sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ==", "dev": true, - "requires": { + "dependencies": { "currently-unhandled": "^0.4.1", "signal-exit": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "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 + "node_modules/lowercase-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", + "integrity": "sha512-RPlX0+PHuvxVDZ7xX+EBVAp4RsVxP/TdDSN2mJYdiq1Lc4Hz7EUSjUI7RZrKKlmrIzVhf6Jo2stj7++gVarS0A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "lpad-align": { + "node_modules/lpad-align": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/lpad-align/-/lpad-align-1.1.2.tgz", - "integrity": "sha1-IfYArBwwlcPG5JfuZyce4ISB/p4=", + "integrity": "sha512-MMIcFmmR9zlGZtBcFOows6c2COMekHCIFJz3ew/rRpKZ1wR4mXDPzvcVqLarux8M33X4TPSq2Jdw8WJj0q0KbQ==", "dev": true, - "requires": { + "dependencies": { "get-stdin": "^4.0.1", "indent-string": "^2.1.0", "longest": "^1.0.0", "meow": "^3.3.0" + }, + "bin": { + "lpad-align": "cli.js" + }, + "engines": { + "node": ">=0.10.0" } }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "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==", "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "dependencies": { + "yallist": "^3.0.2" } }, - "make-dir": { + "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, - "requires": { + "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" } }, - "map-cache": { + "node_modules/map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "map-obj": { + "node_modules/map-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "map-visit": { + "node_modules/map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", "dev": true, - "requires": { + "dependencies": { "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "markdown-link": { + "node_modules/markdown-link": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/markdown-link/-/markdown-link-0.1.1.tgz", - "integrity": "sha1-MsXGUZmmRXMWMi0eQinRNAfIx88=", - "dev": true + "integrity": "sha512-TurLymbyLyo+kAUUAV9ggR9EPcDjP/ctlv9QAFiqUH7c+t6FlsbivPo9OKTU8xdOx9oNd2drW/Fi5RRElQbUqA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "markdown-toc": { + "node_modules/markdown-toc": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/markdown-toc/-/markdown-toc-1.2.0.tgz", "integrity": "sha512-eOsq7EGd3asV0oBfmyqngeEIhrbkc7XVP63OwcJBIhH2EpG2PzFcbZdhy1jutXSlRBBVMNXHvMtSr5LAxSUvUg==", "dev": true, - "requires": { + "dependencies": { "concat-stream": "^1.5.2", "diacritics-map": "^0.1.0", "gray-matter": "^2.1.0", @@ -5741,43 +7958,65 @@ "repeat-string": "^1.6.1", "strip-color": "^0.1.0" }, + "bin": { + "markdown-toc": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/markdown-toc/node_modules/autolinker": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-0.28.1.tgz", + "integrity": "sha512-zQAFO1Dlsn69eXaO6+7YZc+v84aquQKbwpzCE3L0stj56ERn9hutFxPopViLjo9G+rWwjozRhgS5KJ25Xy19cQ==", + "dev": true, "dependencies": { - "remarkable": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/remarkable/-/remarkable-1.7.4.tgz", - "integrity": "sha512-e6NKUXgX95whv7IgddywbeN/ItCkWbISmc2DiqHJb0wTrqZIexqdco5b8Z3XZoo/48IdNVKM9ZCvTPJ4F5uvhg==", - "dev": true, - "requires": { - "argparse": "^1.0.10", - "autolinker": "~0.28.0" - } - } + "gulp-header": "^1.7.1" + } + }, + "node_modules/markdown-toc/node_modules/remarkable": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/remarkable/-/remarkable-1.7.4.tgz", + "integrity": "sha512-e6NKUXgX95whv7IgddywbeN/ItCkWbISmc2DiqHJb0wTrqZIexqdco5b8Z3XZoo/48IdNVKM9ZCvTPJ4F5uvhg==", + "dev": true, + "dependencies": { + "argparse": "^1.0.10", + "autolinker": "~0.28.0" + }, + "bin": { + "remarkable": "bin/remarkable.js" + }, + "engines": { + "node": ">= 0.10.0" } }, - "math-random": { + "node_modules/math-random": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", "dev": true }, - "mdn-data": { + "node_modules/mdn-data": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", "dev": true }, - "media-typer": { + "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } }, - "meow": { + "node_modules/meow": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "integrity": "sha512-TNdwZs0skRlpPpCUK25StC4VH+tP5GgeY1HQOOGP+lQ2xtdkN2VtT/5tiX9k3IWpkBPV9b3LsAWXn4GGi/PrSA==", "dev": true, - "requires": { + "dependencies": { "camelcase-keys": "^2.0.0", "decamelize": "^1.1.2", "loud-rejection": "^1.0.0", @@ -5788,38 +8027,47 @@ "read-pkg-up": "^1.0.1", "redent": "^1.0.0", "trim-newlines": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "merge-descriptors": { + "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", "dev": true }, - "merge2": { + "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 + "dev": true, + "engines": { + "node": ">= 8" + } }, - "methods": { + "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } }, - "microevent.ts": { + "node_modules/microevent.ts": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/microevent.ts/-/microevent.ts-0.1.1.tgz", "integrity": "sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g==", "dev": true }, - "micromatch": { + "node_modules/micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, - "requires": { + "dependencies": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", "braces": "^2.3.1", @@ -5833,104 +8081,154 @@ "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" } }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true + "node_modules/micromatch/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } }, - "mime-db": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", - "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", - "dev": true + "node_modules/micromatch/node_modules/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, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } }, - "mime-types": { - "version": "2.1.27", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", - "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "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==", "dev": true, - "requires": { - "mime-db": "1.44.0" + "engines": { + "node": ">= 0.6" } }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true + "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==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } }, - "mimic-response": { + "node_modules/mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "minimatch": { + "node_modules/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, - "requires": { + "dependencies": { "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true + "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" + } }, - "mixin-deep": { + "node_modules/mixin-deep": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "dev": true, - "requires": { + "dependencies": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/node_modules/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, "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, - "requires": { - "is-plain-object": "^2.0.4" - } - } + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.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==", + "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, - "requires": { - "minimist": "^1.2.5" + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" } }, - "ms": { + "node_modules/moo": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz", + "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==", + "dev": true + }, + "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, - "nanomatch": { + "node_modules/nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "dev": true, - "requires": { + "dependencies": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", "define-property": "^2.0.2", @@ -5942,739 +8240,996 @@ "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "node_modules/nanomatch/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/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, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nearley": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.20.1.tgz", + "integrity": "sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==", + "dev": true, + "dependencies": { + "commander": "^2.19.0", + "moo": "^0.5.0", + "railroad-diagrams": "^1.0.0", + "randexp": "0.4.6" + }, + "bin": { + "nearley-railroad": "bin/nearley-railroad.js", + "nearley-test": "bin/nearley-test.js", + "nearley-unparse": "bin/nearley-unparse.js", + "nearleyc": "bin/nearleyc.js" + }, + "funding": { + "type": "individual", + "url": "https://nearley.js.org/#give-to-nearley" + } + }, + "node_modules/nearley/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 }, - "nice-try": { + "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==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, - "node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "dev": true - }, - "node-releases": { - "version": "1.1.60", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.60.tgz", - "integrity": "sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA==", + "node_modules/node-releases": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.9.tgz", + "integrity": "sha512-2xfmOrRkGogbTK9R6Leda0DGiXeY3p2NJpy4+gNCffdUvV6mdEJnaDEic1i3Ec2djAo8jWYoJMR5PB0MSMpxUA==", "dev": true }, - "normalize-package-data": { + "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, - "requires": { + "dependencies": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } }, - "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 + "node_modules/normalize-package-data/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" + } }, - "normalize-range": { + "node_modules/normalize-range": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", - "dev": true + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "normalize-url": { + "node_modules/normalize-url": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "npm-conf": { + "node_modules/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": { + "dependencies": { "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 - } + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-conf/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" } }, - "npm-run-path": { + "node_modules/npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", "dev": true, - "requires": { + "dependencies": { "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" } }, - "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==", + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "dev": true, - "requires": { - "boolbase": "~1.0.0" + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "num2fraction": { + "node_modules/num2fraction": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", + "integrity": "sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==", "dev": true }, - "oauth-sign": { + "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==", - "dev": true + "dev": true, + "engines": { + "node": "*" + } }, - "object-assign": { + "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "object-copy": { + "node_modules/object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", "dev": true, - "requires": { + "dependencies": { "copy-descriptor": "^0.1.0", "define-property": "^0.2.5", "kind-of": "^3.0.3" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, "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, - "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, - "requires": { - "is-buffer": "^1.1.5" - } - } + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true + "node_modules/object-copy/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-descriptor/node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } }, - "object-keys": { + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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 + "dev": true, + "engines": { + "node": ">= 0.4" + } }, - "object-visit": { + "node_modules/object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", "dev": true, - "requires": { + "dependencies": { "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", + "node_modules/object.entries": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", + "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", + "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.5.tgz", + "integrity": "sha512-yDNzckpM6ntyQiGTik1fKV1DcVDRS+w8bvpWNCBanvH5LfRX9O8WTHqQzG4RZwRAM4I0oU7TV11Lj5v0g20ibw==", + "dev": true, + "dependencies": { + "array.prototype.reduce": "^1.0.5", + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "object.pick": { + "node_modules/object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", "dev": true, - "requires": { + "dependencies": { "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "object.values": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", - "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "node_modules/object.values": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", + "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "has": "^1.0.3" + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "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==", "dev": true, - "requires": { + "dependencies": { "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" } }, - "once": { + "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, - "requires": { + "dependencies": { "wrappy": "1" } }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "open": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz", - "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==", + "node_modules/open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", "dev": true, - "requires": { - "is-wsl": "^1.1.0" + "dependencies": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "optipng-bin": { + "node_modules/optipng-bin": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/optipng-bin/-/optipng-bin-5.1.0.tgz", "integrity": "sha512-9baoqZTNNmXQjq/PQTWEXbVV3AMO2sI/GaaqZJZ8SExfAzjijeAP7FEeT+TtyumSw7gr0PZtSUYB/Ke7iHQVKA==", "dev": true, - "requires": { + "hasInstallScript": true, + "dependencies": { "bin-build": "^3.0.0", "bin-wrapper": "^4.0.0", "logalot": "^2.0.0" + }, + "bin": { + "optipng": "cli.js" + }, + "engines": { + "node": ">=6" } }, - "original": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", - "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", - "dev": true, - "requires": { - "url-parse": "^1.4.3" - } - }, - "os-filter-obj": { + "node_modules/os-filter-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/os-filter-obj/-/os-filter-obj-2.0.0.tgz", "integrity": "sha512-uksVLsqG3pVdzzPvmAHpBK0wKxYItuzZr7SziusRPoz67tGV8rL1szZ6IdeUrbqLjGDwApBtN29eEE3IqGHOjg==", "dev": true, - "requires": { + "dependencies": { "arch": "^2.1.0" + }, + "engines": { + "node": ">=4" } }, - "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 - }, - "p-cancelable": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=4" + } }, - "p-event": { + "node_modules/p-event": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/p-event/-/p-event-1.3.0.tgz", - "integrity": "sha1-jmtPT2XHK8W2/ii3XtqHT5akoIU=", + "integrity": "sha512-hV1zbA7gwqPVFcapfeATaNjQ3J0NuzorHPyG8GPL9g/Y/TplWVBVoCKCXL6Ej2zscrCEv195QNWJXuBH6XZuzA==", "dev": true, - "requires": { + "dependencies": { "p-timeout": "^1.1.1" + }, + "engines": { + "node": ">=4" } }, - "p-finally": { + "node_modules/p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "dev": true, + "engines": { + "node": ">=4" + } }, - "p-is-promise": { + "node_modules/p-is-promise": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", - "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", - "dev": true + "integrity": "sha512-zL7VE4JVS2IFSkR2GQKDSPEVxkoH43/p7oEnwpdCndKYJO0HVeRB7fA8TJwuLOTBREtK0ea8eHaxdwcpob5dmg==", + "dev": true, + "engines": { + "node": ">=4" + } }, - "p-limit": { + "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, - "requires": { + "dependencies": { "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "p-locate": { + "node_modules/p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, - "requires": { + "dependencies": { "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" } }, - "p-map-series": { + "node_modules/p-map-series": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-map-series/-/p-map-series-1.0.0.tgz", - "integrity": "sha1-v5j+V1cFZYqeE1G++4WuTB8Hvco=", + "integrity": "sha512-4k9LlvY6Bo/1FcIdV33wqZQES0Py+iKISU9Uc8p8AjWoZPnFKMpVIVD3s0EYn4jzLh1I+WeUZkJ0Yoa4Qfw3Kg==", "dev": true, - "requires": { + "dependencies": { "p-reduce": "^1.0.0" + }, + "engines": { + "node": ">=4" } }, - "p-pipe": { + "node_modules/p-pipe": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/p-pipe/-/p-pipe-1.2.0.tgz", - "integrity": "sha1-SxoROZoRUgpneQ7loMHViB1r7+k=", - "dev": true + "integrity": "sha512-IA8SqjIGA8l9qOksXJvsvkeQ+VGb0TAzNCzvKvz9wt5wWLqfWbV6fXy43gpR2L4Te8sOq3S+Ql9biAaMKPdbtw==", + "dev": true, + "engines": { + "node": ">=4" + } }, - "p-reduce": { + "node_modules/p-reduce": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", - "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=", - "dev": true + "integrity": "sha512-3Tx1T3oM1xO/Y8Gj0sWyE78EIJZ+t+aEmXUdvQgvGmSMri7aPTHoovbXEreWKkL5j21Er60XAWLTzKbAKYOujQ==", + "dev": true, + "engines": { + "node": ">=4" + } }, - "p-timeout": { + "node_modules/p-timeout": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", - "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", + "integrity": "sha512-gb0ryzr+K2qFqFv6qi3khoeqMZF/+ajxQipEF6NteZVnvz9tzdsfAVj3lYtn1gAXvH5lfLwfxEII799gt/mRIA==", "dev": true, - "requires": { + "dependencies": { "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=4" } }, - "p-try": { + "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 + "dev": true, + "engines": { + "node": ">=6" + } }, - "parse-json": { + "node_modules/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": { + "dependencies": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dev": true, + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", + "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "dev": true, + "dependencies": { + "domhandler": "^5.0.2", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "parseurl": { + "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.8" + } }, - "pascalcase": { + "node_modules/pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true + "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "path-dirname": { + "node_modules/path-dirname": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", "dev": true }, - "path-exists": { + "node_modules/path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "engines": { + "node": ">=4" + } }, - "path-is-absolute": { + "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "path-key": { + "node_modules/path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "engines": { + "node": ">=4" + } }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "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 }, - "path-to-regexp": { + "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", "dev": true }, - "path-type": { + "node_modules/path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, - "requires": { + "dependencies": { "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 - } + "engines": { + "node": ">=4" + } + }, + "node_modules/path-type/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" } }, - "pend": { + "node_modules/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": { + "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", "dev": true }, - "pify": { + "node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "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 + "dev": true, + "engines": { + "node": ">=6" + } }, - "pinkie": { + "node_modules/pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "pinkie-promise": { + "node_modules/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": { + "dependencies": { "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "node_modules/pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", "dev": true, - "requires": { - "node-modules-regexp": "^1.0.0" + "engines": { + "node": ">= 6" } }, - "pkg-dir": { + "node_modules/pkg-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", "dev": true, - "requires": { + "dependencies": { "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", - "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", + "node_modules/pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", "dev": true, - "requires": { - "find-up": "^2.1.0" - }, "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "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, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - } + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "portfinder": { - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", - "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", + "node_modules/portfinder": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", + "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", "dev": true, - "requires": { - "async": "^2.6.2", - "debug": "^3.1.1", - "mkdirp": "^0.5.5" + "dependencies": { + "async": "^2.6.4", + "debug": "^3.2.7", + "mkdirp": "^0.5.6" }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/portfinder/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } + "ms": "^2.1.1" } }, - "posix-character-classes": { + "node_modules/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 - }, - "postcss": { - "version": "7.0.32", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz", - "integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - }, - "dependencies": { - "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" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "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 - }, - "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 - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "postcss-calc": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.3.tgz", - "integrity": "sha512-IB/EAEmZhIMEIhG7Ov4x+l47UaXOS1n2f4FBUk/aKllQhtSCxWhTzn0nJgkqN7fo/jcWySvWTSB6Syk9L+31bA==", + "node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-calc": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz", + "integrity": "sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==", "dev": true, - "requires": { + "dependencies": { "postcss": "^7.0.27", "postcss-selector-parser": "^6.0.2", "postcss-value-parser": "^4.0.2" } }, - "postcss-colormin": { + "node_modules/postcss-colormin": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", "dev": true, - "requires": { + "dependencies": { "browserslist": "^4.0.0", "color": "^3.0.0", "has": "^1.0.0", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "engines": { + "node": ">=6.9.0" } }, - "postcss-convert-values": { + "node_modules/postcss-colormin/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-convert-values": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", "dev": true, - "requires": { + "dependencies": { "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "engines": { + "node": ">=6.9.0" } }, - "postcss-discard-comments": { + "node_modules/postcss-convert-values/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-discard-comments": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", "dev": true, - "requires": { + "dependencies": { "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "postcss-discard-duplicates": { + "node_modules/postcss-discard-duplicates": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", "dev": true, - "requires": { + "dependencies": { "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "postcss-discard-empty": { + "node_modules/postcss-discard-empty": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", "dev": true, - "requires": { + "dependencies": { "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "postcss-discard-overridden": { + "node_modules/postcss-discard-overridden": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", "dev": true, - "requires": { + "dependencies": { "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "postcss-merge-longhand": { + "node_modules/postcss-merge-longhand": { "version": "4.0.11", "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", "dev": true, - "requires": { + "dependencies": { "css-color-names": "0.0.4", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0", "stylehacks": "^4.0.0" }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "engines": { + "node": ">=6.9.0" } }, - "postcss-merge-rules": { + "node_modules/postcss-merge-longhand/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-merge-rules": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", "dev": true, - "requires": { + "dependencies": { "browserslist": "^4.0.0", "caniuse-api": "^3.0.0", "cssnano-util-same-parent": "^4.0.0", @@ -6682,64 +9237,70 @@ "postcss-selector-parser": "^3.0.0", "vendors": "^1.0.0" }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-merge-rules/node_modules/postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, "dependencies": { - "postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dev": true, - "requires": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=8" } }, - "postcss-minify-font-values": { + "node_modules/postcss-minify-font-values": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", "dev": true, - "requires": { + "dependencies": { "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "engines": { + "node": ">=6.9.0" } }, - "postcss-minify-gradients": { + "node_modules/postcss-minify-font-values/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-minify-gradients": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", "dev": true, - "requires": { + "dependencies": { "cssnano-util-get-arguments": "^4.0.0", "is-color-stop": "^1.0.0", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "engines": { + "node": ">=6.9.0" } }, - "postcss-minify-params": { + "node_modules/postcss-minify-gradients/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-minify-params": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", "dev": true, - "requires": { + "dependencies": { "alphanum-sort": "^1.0.0", "browserslist": "^4.0.0", "cssnano-util-get-arguments": "^4.0.0", @@ -6747,1765 +9308,2817 @@ "postcss-value-parser": "^3.0.0", "uniqs": "^2.0.0" }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "engines": { + "node": ">=6.9.0" } }, - "postcss-minify-selectors": { + "node_modules/postcss-minify-params/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-minify-selectors": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", "dev": true, - "requires": { + "dependencies": { "alphanum-sort": "^1.0.0", "has": "^1.0.0", "postcss": "^7.0.0", "postcss-selector-parser": "^3.0.0" }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-selectors/node_modules/postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, "dependencies": { - "postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dev": true, - "requires": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=8" } }, - "postcss-normalize-charset": { + "node_modules/postcss-normalize-charset": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", "dev": true, - "requires": { + "dependencies": { "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "postcss-normalize-display-values": { + "node_modules/postcss-normalize-display-values": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", "dev": true, - "requires": { + "dependencies": { "cssnano-util-get-match": "^4.0.0", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "engines": { + "node": ">=6.9.0" } }, - "postcss-normalize-positions": { + "node_modules/postcss-normalize-display-values/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-positions": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", "dev": true, - "requires": { + "dependencies": { "cssnano-util-get-arguments": "^4.0.0", "has": "^1.0.0", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "engines": { + "node": ">=6.9.0" } }, - "postcss-normalize-repeat-style": { + "node_modules/postcss-normalize-positions/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-repeat-style": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", "dev": true, - "requires": { + "dependencies": { "cssnano-util-get-arguments": "^4.0.0", "cssnano-util-get-match": "^4.0.0", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "engines": { + "node": ">=6.9.0" } }, - "postcss-normalize-string": { + "node_modules/postcss-normalize-repeat-style/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-string": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", "dev": true, - "requires": { + "dependencies": { "has": "^1.0.0", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "engines": { + "node": ">=6.9.0" } }, - "postcss-normalize-timing-functions": { + "node_modules/postcss-normalize-string/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-timing-functions": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", "dev": true, - "requires": { + "dependencies": { "cssnano-util-get-match": "^4.0.0", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "engines": { + "node": ">=6.9.0" } }, - "postcss-normalize-unicode": { + "node_modules/postcss-normalize-timing-functions/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-unicode": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", "dev": true, - "requires": { + "dependencies": { "browserslist": "^4.0.0", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "engines": { + "node": ">=6.9.0" } }, - "postcss-normalize-url": { + "node_modules/postcss-normalize-unicode/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-url": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", "dev": true, - "requires": { + "dependencies": { "is-absolute-url": "^2.0.0", "normalize-url": "^3.0.0", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "engines": { + "node": ">=6.9.0" } }, - "postcss-normalize-whitespace": { + "node_modules/postcss-normalize-url/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-whitespace": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", "dev": true, - "requires": { + "dependencies": { "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "engines": { + "node": ">=6.9.0" } }, - "postcss-ordered-values": { + "node_modules/postcss-normalize-whitespace/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-ordered-values": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", "dev": true, - "requires": { + "dependencies": { "cssnano-util-get-arguments": "^4.0.0", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "engines": { + "node": ">=6.9.0" } }, - "postcss-reduce-initial": { + "node_modules/postcss-ordered-values/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-reduce-initial": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", "dev": true, - "requires": { + "dependencies": { "browserslist": "^4.0.0", "caniuse-api": "^3.0.0", "has": "^1.0.0", "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "postcss-reduce-transforms": { + "node_modules/postcss-reduce-transforms": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", "dev": true, - "requires": { + "dependencies": { "cssnano-util-get-match": "^4.0.0", "has": "^1.0.0", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "engines": { + "node": ">=6.9.0" } }, - "postcss-selector-parser": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", - "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==", + "node_modules/postcss-reduce-transforms/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", + "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", "dev": true, - "requires": { + "dependencies": { "cssesc": "^3.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" } }, - "postcss-svgo": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz", - "integrity": "sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==", + "node_modules/postcss-svgo": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.3.tgz", + "integrity": "sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==", "dev": true, - "requires": { - "is-svg": "^3.0.0", + "dependencies": { "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0", "svgo": "^1.0.0" }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "engines": { + "node": ">=6.9.0" } }, - "postcss-unique-selectors": { + "node_modules/postcss-svgo/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-unique-selectors": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", "dev": true, - "requires": { + "dependencies": { "alphanum-sort": "^1.0.0", "postcss": "^7.0.0", "uniqs": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "dev": true }, - "prepend-http": { + "node_modules/prepend-http": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true + "integrity": "sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "prismjs": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.21.0.tgz", - "integrity": "sha512-uGdSIu1nk3kej2iZsLyDoJ7e9bnPzIgY0naW/HdknGj61zScaprVEVGHrPoXqI+M9sP0NDnTK2jpkvmldpuqDw==", + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", "dev": true, - "requires": { - "clipboard": "^2.0.0" + "engines": { + "node": ">=6" } }, - "process-nextick-args": { + "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 }, - "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "node_modules/prompts": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz", + "integrity": "sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "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, - "requires": { + "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", - "react-is": "^16.8.1" + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types-exact": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/prop-types-exact/-/prop-types-exact-1.2.0.tgz", + "integrity": "sha512-K+Tk3Kd9V0odiXFP9fwDHUYRyvK3Nun3GVyPapSIs5OBkITAm15W0CPFD/YKTkMUAbc0b9CUwRQp2ybiBIq+eA==", + "dev": true, + "dependencies": { + "has": "^1.0.3", + "object.assign": "^4.1.0", + "reflect.ownkeys": "^0.2.0" } }, - "proto-list": { + "node_modules/proto-list": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", "dev": true }, - "proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "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==", "dev": true, - "requires": { - "forwarded": "~0.1.2", + "dependencies": { + "forwarded": "0.2.0", "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" } }, - "pseudomap": { + "node_modules/pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", "dev": true }, - "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", "dev": true }, - "pump": { + "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, - "requires": { + "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } }, - "q": { + "node_modules/q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", - "dev": true + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "dev": true, + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "query-string": { + "node_modules/query-string": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", "dev": true, - "requires": { + "dependencies": { "decode-uri-component": "^0.2.0", "object-assign": "^4.1.0", "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "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==", + "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/raf": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "dev": true, + "dependencies": { + "performance-now": "^2.1.0" + } + }, + "node_modules/railroad-diagrams": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz", + "integrity": "sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==", "dev": true }, - "randomatic": { + "node_modules/randexp": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz", + "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==", + "dev": true, + "dependencies": { + "discontinuous-range": "1.0.0", + "ret": "~0.1.10" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/randomatic": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", "dev": true, - "requires": { + "dependencies": { "is-number": "^4.0.0", "kind-of": "^6.0.0", "math-random": "^1.0.1" }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/randomatic/node_modules/is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "range-parser": { + "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==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.6" + } }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "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==", "dev": true, - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" } }, - "react": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react/-/react-16.13.1.tgz", - "integrity": "sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==", + "node_modules/react": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", + "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", "dev": true, - "requires": { + "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2" + }, + "engines": { + "node": ">=0.10.0" } }, - "react-dev-utils": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-9.1.0.tgz", - "integrity": "sha512-X2KYF/lIGyGwP/F/oXgGDF24nxDA2KC4b7AFto+eqzc/t838gpSGiaU8trTqHXOohuLxxc5qi1eDzsl9ucPDpg==", + "node_modules/react-dev-utils": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.4.tgz", + "integrity": "sha512-dx0LvIGHcOPtKbeiSUM4jqpBl3TcY7CDjZdfOIcKeznE7BWr9dg0iPG90G5yfVQ+p/rGNMXdbfStvzQZEVEi4A==", "dev": true, - "requires": { - "@babel/code-frame": "7.5.5", + "dependencies": { + "@babel/code-frame": "7.10.4", "address": "1.1.2", - "browserslist": "4.7.0", + "browserslist": "4.14.2", "chalk": "2.4.2", - "cross-spawn": "6.0.5", + "cross-spawn": "7.0.3", "detect-port-alt": "1.1.6", - "escape-string-regexp": "1.0.5", - "filesize": "3.6.1", - "find-up": "3.0.0", - "fork-ts-checker-webpack-plugin": "1.5.0", + "escape-string-regexp": "2.0.0", + "filesize": "6.1.0", + "find-up": "4.1.0", + "fork-ts-checker-webpack-plugin": "4.1.6", "global-modules": "2.0.0", - "globby": "8.0.2", + "globby": "11.0.1", "gzip-size": "5.1.1", - "immer": "1.10.0", - "inquirer": "6.5.0", + "immer": "8.0.1", "is-root": "2.1.0", - "loader-utils": "1.2.3", - "open": "^6.3.0", - "pkg-up": "2.0.0", - "react-error-overlay": "^6.0.3", + "loader-utils": "2.0.0", + "open": "^7.0.2", + "pkg-up": "3.1.0", + "prompts": "2.4.0", + "react-error-overlay": "^6.0.9", "recursive-readdir": "2.2.2", "shell-quote": "1.7.2", - "sockjs-client": "1.4.0", - "strip-ansi": "5.2.0", + "strip-ansi": "6.0.0", "text-table": "0.2.0" }, - "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "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 - }, - "browserslist": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.7.0.tgz", - "integrity": "sha512-9rGNDtnj+HaahxiVV38Gn8n8Lr8REKsel68v1sPFfIGEK6uSXTY3h9acgiT1dZVtOOUtifo/Dn8daDQ5dUgVsA==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30000989", - "electron-to-chromium": "^1.3.247", - "node-releases": "^1.1.29" - } - }, - "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" - } - }, - "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, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "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 - }, - "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" - } - } + "engines": { + "node": ">=10" } }, - "react-dom": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.1.tgz", - "integrity": "sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag==", + "node_modules/react-dev-utils/node_modules/@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.19.1" + "dependencies": { + "@babel/highlight": "^7.10.4" } }, - "react-error-overlay": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.7.tgz", - "integrity": "sha512-TAv1KJFh3RhqxNvhzxj6LeT5NWklP6rDr2a0jaTfsZ5wSZWHOGeqQyejUp3xxLfPt2UpyJEcVQB/zyPcmonNFA==", - "dev": true - }, - "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 - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "node_modules/react-dev-utils/node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - }, - "dependencies": { - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } + "engines": { + "node": ">= 8" } }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "node_modules/react-dev-utils/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - } + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "node_modules/react-dev-utils/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, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "engines": { + "node": ">=8" } }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "node_modules/react-dev-utils/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, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" } }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "node_modules/react-dev-utils/node_modules/browserslist": { + "version": "4.14.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.2.tgz", + "integrity": "sha512-HI4lPveGKUR0x2StIz+2FXfDk9SfVMrxn6PLh1JeGUwcuoDkdKZebWiyLRJ68iIPDpMI4JLVDf7S7XzslgWOhw==", "dev": true, - "requires": { - "resolve": "^1.1.6" + "dependencies": { + "caniuse-lite": "^1.0.30001125", + "electron-to-chromium": "^1.3.564", + "escalade": "^3.0.2", + "node-releases": "^1.1.61" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" } }, - "recursive-readdir": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz", - "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==", + "node_modules/react-dev-utils/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, - "requires": { - "minimatch": "3.0.4" + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" } }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "node_modules/react-dev-utils/node_modules/chalk/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, - "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" + "engines": { + "node": ">=0.8.0" } }, - "regenerate": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz", - "integrity": "sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==", - "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==", + "node_modules/react-dev-utils/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "requires": { - "regenerate": "^1.4.0" + "dependencies": { + "color-name": "1.1.3" } }, - "regenerator-runtime": { - "version": "0.13.7", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", + "node_modules/react-dev-utils/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "regenerator-transform": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", - "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", + "node_modules/react-dev-utils/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==", "dev": true, - "requires": { - "@babel/runtime": "^7.8.4" + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" } }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "node_modules/react-dev-utils/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, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "regexpu-core": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.0.tgz", - "integrity": "sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==", + "node_modules/react-dev-utils/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, - "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" + "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" } }, - "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.4", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz", - "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==", + "node_modules/react-dev-utils/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, - "requires": { - "jsesc": "~0.5.0" - }, "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - } + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "remarkable": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remarkable/-/remarkable-2.0.1.tgz", - "integrity": "sha512-YJyMcOH5lrR+kZdmB0aJJ4+93bEojRZ1HGDn9Eagu6ibg7aVZhc3OWbbShRid+Q5eAfsEqWxpe+g5W5nYNfNiA==", + "node_modules/react-dev-utils/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, - "requires": { - "argparse": "^1.0.10", - "autolinker": "^3.11.0" + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, + "engines": { + "node": ">=8" + } + }, + "node_modules/react-dev-utils/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": { - "autolinker": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-3.14.1.tgz", - "integrity": "sha512-yvsRHIaY51EYDml6MGlbqyJGfl4n7zezGYf+R7gvM8c5LNpRGc4SISkvgAswSS8SWxk/OrGCylKV9mJyVstz7w==", - "dev": true, - "requires": { - "tslib": "^1.9.3" - } - } + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" } }, - "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 + "node_modules/react-dev-utils/node_modules/globby": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true + "node_modules/react-dev-utils/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==", + "dev": true, + "engines": { + "node": ">=4" + } }, - "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 + "node_modules/react-dev-utils/node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "node_modules/react-dev-utils/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, - "requires": { - "is-finite": "^1.0.0" + "engines": { + "node": ">=0.12.0" } }, - "replace-ext": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", - "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", - "dev": true + "node_modules/react-dev-utils/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" + } }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "node_modules/react-dev-utils/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, - "requires": { - "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" + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" } }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "node_modules/react-dev-utils/node_modules/node-releases": { + "version": "1.1.77", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.77.tgz", + "integrity": "sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ==", "dev": true }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "node_modules/react-dev-utils/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, - "requires": { - "path-parse": "^1.0.6" + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" } }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true + "node_modules/react-dev-utils/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "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 + "node_modules/react-dev-utils/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==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "node_modules/react-dev-utils/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, - "requires": { - "lowercase-keys": "^1.0.0" + "engines": { + "node": ">=8" } }, - "restore-cursor": { + "node_modules/react-dev-utils/node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "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 - }, - "rgb-regex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", - "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=", - "dev": true + "node_modules/react-dev-utils/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==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "rgba-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", - "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "node_modules/react-dev-utils/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "requires": { - "glob": "^7.1.3" + "engines": { + "node": ">=8" } }, - "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 - }, - "rxjs": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz", - "integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==", + "node_modules/react-dev-utils/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==", "dev": true, - "requires": { - "tslib": "^1.9.0" + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "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/react-dev-utils/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" + } }, - "safe-json-parse": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz", - "integrity": "sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=", - "dev": true + "node_modules/react-dev-utils/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "node_modules/react-dom": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", + "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", "dev": true, - "requires": { - "ret": "~0.1.10" + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.19.1" + }, + "peerDependencies": { + "react": "^16.14.0" } }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "node_modules/react-error-overlay": { + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", + "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==", "dev": true }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "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 }, - "scheduler": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", - "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", + "node_modules/react-test-renderer": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.14.0.tgz", + "integrity": "sha512-L8yPjqPE5CZO6rKsKXRO/rVPiaCOy0tQQJbC+UjPNlobl5mad59lvPjwFsQHTvL03caVDIVr9x9/OSgDe6I5Eg==", "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "dependencies": { + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "react-is": "^16.8.6", + "scheduler": "^0.19.1" + }, + "peerDependencies": { + "react": "^16.14.0" } }, - "seek-bzip": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", - "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", + "node_modules/read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", "dev": true, - "requires": { - "commander": "^2.8.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 - } + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "select": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", - "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", + "node_modules/read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "semver-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz", - "integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==", - "dev": true + "dependencies": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } }, - "semver-truncate": { + "node_modules/read-pkg-up/node_modules/find-up": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/semver-truncate/-/semver-truncate-1.1.2.tgz", - "integrity": "sha1-V/Qd5pcHpicJp+AQS6IRcQnqR+g=", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", "dev": true, - "requires": { - "semver": "^5.3.0" + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.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, - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - } + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "node_modules/read-pkg/node_modules/path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" + "dependencies": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "set-getter": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.0.tgz", - "integrity": "sha1-12nBgsnVpR9AkUXy+6guXoboA3Y=", + "node_modules/read-pkg/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, - "requires": { - "to-object-path": "^0.3.0" + "engines": { + "node": ">=0.10.0" } }, - "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==", + "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, - "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, - "requires": { - "is-extendable": "^0.1.0" - } - } + "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" } }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "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 }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", "dev": true, - "requires": { - "shebang-regex": "^1.0.0" + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/recursive-readdir": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz", + "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==", + "dev": true, + "dependencies": { + "minimatch": "3.0.4" + }, + "engines": { + "node": ">=0.10.0" } }, - "shebang-regex": { + "node_modules/redent": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha512-qtW5hKzGQZqKoh6JNSD+4lfitfPKGz42e6QwiRmPM5mmKtR0N41AbJRYu0xJi7nhOJ4WDgRkKvAk6tw4WIwR4g==", + "dev": true, + "dependencies": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/reflect.ownkeys": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz", + "integrity": "sha512-qOLsBKHCpSOFKK1NUOCGC5VyeufB6lEsFe92AL2bhIJsacZS1qdoOZSbPk3MYKuT2cFlRDnulKXuuElIrMjGUg==", "dev": true }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", + "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 }, - "shelljs": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", - "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", + "node_modules/regenerate-unicode-properties": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", + "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", "dev": true, - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" } }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "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==", "dev": true }, - "simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "node_modules/regenerator-transform": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", + "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", "dev": true, - "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==", - "dev": true - } + "@babel/runtime": "^7.8.4" } }, - "sitemap": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-3.2.2.tgz", - "integrity": "sha512-TModL/WU4m2q/mQcrDgNANn0P4LwprM9MMvG4hu5zP4c6IIKs2YLTu6nXXnNr8ODW/WFtxKggiJ1EGn2W0GNmg==", + "node_modules/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, - "requires": { - "lodash.chunk": "^4.2.0", - "lodash.padstart": "^4.6.1", - "whatwg-url": "^7.0.0", - "xmlbuilder": "^13.0.0" + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "node_modules/regex-not/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", "dev": 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" - }, "dependencies": { - "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" - } - }, - "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, - "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, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.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==", + "node_modules/regex-not/node_modules/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, - "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, - "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, - "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, - "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, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" } }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "node_modules/regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", "dev": 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, - "requires": { - "is-buffer": "^1.1.5" - } - } + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "sockjs-client": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz", - "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==", + "node_modules/regexpu-core": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", + "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", "dev": true, - "requires": { - "debug": "^3.2.5", - "eventsource": "^1.0.7", - "faye-websocket": "~0.11.1", - "inherits": "^2.0.3", - "json3": "^3.3.2", - "url-parse": "^1.4.3" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsgen": "^0.7.1", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } }, - "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "node_modules/regjsgen": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", + "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==", + "dev": true + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", "dev": true, - "requires": { - "is-plain-obj": "^1.0.0" + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" } }, - "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=", + "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, - "requires": { - "sort-keys": "^1.0.0" + "bin": { + "jsesc": "bin/jsesc" } }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "node_modules/remarkable": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remarkable/-/remarkable-2.0.1.tgz", + "integrity": "sha512-YJyMcOH5lrR+kZdmB0aJJ4+93bEojRZ1HGDn9Eagu6ibg7aVZhc3OWbbShRid+Q5eAfsEqWxpe+g5W5nYNfNiA==", + "dev": true, + "dependencies": { + "argparse": "^1.0.10", + "autolinker": "^3.11.0" + }, + "bin": { + "remarkable": "bin/remarkable.js" + }, + "engines": { + "node": ">= 6.0.0" + } }, - "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==", + "node_modules/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, - "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" + "engines": { + "node": ">=0.10.0" } }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "engines": { + "node": ">=0.10" + } + }, + "node_modules/repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A==", + "dev": true, + "dependencies": { + "is-finite": "^1.0.0" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/replace-ext": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", + "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, "dependencies": { - "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 - } + "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" } }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true + "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==", + "dev": true, + "engines": { + "node": ">=0.6" + } }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "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, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "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" } }, - "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==", + "node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", + "deprecated": "https://github.com/lydell/resolve-url#deprecated", "dev": true }, - "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==", + "node_modules/responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "dependencies": { + "lowercase-keys": "^1.0.0" } }, - "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", - "dev": true + "node_modules/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, + "engines": { + "node": ">=0.12" + } }, - "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==", + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, - "requires": { - "extend-shallow": "^3.0.0" + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "node_modules/rgb-regex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", + "integrity": "sha512-gDK5mkALDFER2YLqH6imYvK6g02gpNGM4ILDZ472EwWfXZnC2ZEpoB2ECXTyOVUKuk/bPJZMzwQPBYICzP+D3w==", "dev": true }, - "squeak": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/squeak/-/squeak-1.3.0.tgz", - "integrity": "sha1-MwRQN7ZDiLVnZ0uEMiplIQc5FsM=", + "node_modules/rgba-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", + "integrity": "sha512-zgn5OjNQXLUTdq8m17KdaicF6w89TZs8ZU8y0AYENIU6wG8GG6LLm0yLSiPY8DmaYmHdgRW8rnApjoT0fQRfMg==", + "dev": true + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, - "requires": { - "chalk": "^1.0.0", - "console-stream": "^0.1.1", - "lpad-align": "^1.0.1" + "dependencies": { + "glob": "^7.1.3" }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/rst-selector-parser": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz", + "integrity": "sha512-nDG1rZeP6oFTLN6yNDV/uiAvs1+FS/KlrEwh7+y7dpuApDBy6bI2HTBcc0/V8lv9OTqfyD34eF7au2pm8aBbhA==", + "dev": true, "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } + "lodash.flattendeep": "^4.4.0", + "nearley": "^2.7.10" + } + }, + "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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "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 + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true + { + "type": "consulting", + "url": "https://feross.org/support" } + ], + "dependencies": { + "queue-microtask": "^1.2.2" } }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "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==", "dev": true, - "requires": { - "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" - } + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "node_modules/safe-json-parse": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz", + "integrity": "sha512-o0JmTu17WGUaUOHa1l0FPGXKBfijbxK6qoHzlkihsDXxzBHvJcA7zgviKR92Xs841rX9pK16unfphLq0/KqX7A==", "dev": true }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "node_modules/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", "dev": 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, - "requires": { - "is-descriptor": "^0.1.0" - } - } + "ret": "~0.1.10" } }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true }, - "string-template": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", - "integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=", + "node_modules/scheduler": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", + "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", + "dev": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "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 }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "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": "2.0.0", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz", + "integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/semver-truncate": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/semver-truncate/-/semver-truncate-1.1.2.tgz", + "integrity": "sha512-V1fGg9i4CL3qesB6U0L6XAm4xOJiHmt4QAacazumuasc03BvtFGIMCduv01JWQ69Nv+JST9TqhSCiJoxoY031w==", "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "dependencies": { + "semver": "^5.3.0" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/semver-truncate/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/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } + "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" } }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "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==", "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "dependencies": { + "ms": "2.0.0" } }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "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==", + "dev": true + }, + "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==", + "dev": true + }, + "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==", + "dev": true, + "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-getter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.1.tgz", + "integrity": "sha512-9sVWOy+gthr+0G9DzqqLaYNA7+5OKkSmcqjL9cBpDEaZrr3ShQlyX2cZ/O/ozE41oxn/Tt0LGEM/w4Rub3A3gw==", + "dev": true, + "dependencies": { + "to-object-path": "^0.3.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shell-quote": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", + "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", + "dev": true + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dev": true, + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "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==", + "dev": true, + "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/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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/sitemap": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-3.2.2.tgz", + "integrity": "sha512-TModL/WU4m2q/mQcrDgNANn0P4LwprM9MMvG4hu5zP4c6IIKs2YLTu6nXXnNr8ODW/WFtxKggiJ1EGn2W0GNmg==", + "dev": true, + "dependencies": { + "lodash.chunk": "^4.2.0", + "lodash.padstart": "^4.6.1", + "whatwg-url": "^7.0.0", + "xmlbuilder": "^13.0.0" + }, + "engines": { + "node": ">=6.0.0", + "npm": ">=4.0.0" + } + }, + "node_modules/slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "dependencies": { + "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" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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, + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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, + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/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/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/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/snapdragon/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==", + "dev": true, + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sort-keys-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", + "integrity": "sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==", + "dev": true, + "dependencies": { + "sort-keys": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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/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==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "dev": true, + "dependencies": { + "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" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/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==", + "deprecated": "See https://github.com/lydell/source-map-url#deprecated", + "dev": true + }, + "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/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, + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/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, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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/squeak": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/squeak/-/squeak-1.3.0.tgz", + "integrity": "sha512-YQL1ulInM+ev8nXX7vfXsCsDh6IqXlrremc1hzi77776BtpWgYJUMto3UM05GSAaGzJgWekszjoKDrVNB5XG+A==", + "dev": true, + "dependencies": { + "chalk": "^1.0.0", + "console-stream": "^0.1.1", + "lpad-align": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/squeak/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/squeak/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/squeak/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/squeak/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/squeak/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/squeak/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "dev": true, + "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/stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility", + "dev": true + }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", + "dev": true, + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", + "dev": true, + "engines": { + "node": ">=0.10.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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/string-template": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", + "integrity": "sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw==", + "dev": true + }, + "node_modules/string.prototype.trim": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", + "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", + "dev": true, + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-color": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/strip-color/-/strip-color-0.1.0.tgz", + "integrity": "sha512-p9LsUieSjWNNAxVCXLeilaDlmuUOrDS5/dF9znM1nZc7EGX5+zEFC0bEevsNIaldjlks+2jns5Siz6F9iK6jwA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha512-I5iQq6aFMM62fBEAIB/hXzwJD6EEZ0xEGCX2t7oXqaKPIRgt4WruAQ285BISgdkP+HLGWyeGmNJcpIwFeRYRUA==", + "dev": true, + "dependencies": { + "get-stdin": "^4.0.1" + }, + "bin": { + "strip-indent": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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, + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-outer/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "dev": true + }, + "node_modules/stylehacks": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", + "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/stylehacks/node_modules/postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "dependencies": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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/svgo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/svgo/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/svgo/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/svgo/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/svgo/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/svgo/node_modules/css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "node_modules/svgo/node_modules/css-what": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", "dev": true, - "requires": { - "safe-buffer": "~5.1.0" + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" } }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "node_modules/svgo/node_modules/dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", "dev": true, - "requires": { - "ansi-regex": "^2.0.0" + "dependencies": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" } }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "node_modules/svgo/node_modules/domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", "dev": true, - "requires": { - "is-utf8": "^0.2.0" + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" } }, - "strip-color": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/strip-color/-/strip-color-0.1.0.tgz", - "integrity": "sha1-EG9l09PmotlAHKwOsM6LinArT3s=", + "node_modules/svgo/node_modules/domutils/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 }, - "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==", + "node_modules/svgo/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", "dev": true, - "requires": { - "is-natural-number": "^4.0.1" + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "node_modules/svgo/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, - "requires": { - "get-stdin": "^4.0.1" + "engines": { + "node": ">=0.8.0" } }, - "strip-outer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "node_modules/svgo/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==", "dev": true, - "requires": { - "escape-string-regexp": "^1.0.2" - }, - "dependencies": { - "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 - } + "engines": { + "node": ">=4" } }, - "stylehacks": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", - "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", + "node_modules/svgo/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, - "requires": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" - }, "dependencies": { - "postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dev": true, - "requires": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } + "boolbase": "~1.0.0" } }, - "supports-color": { + "node_modules/svgo/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==", "dev": true, - "requires": { + "dependencies": { "has-flag": "^3.0.0" - } - }, - "svgo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", - "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "coa": "^2.0.2", - "css-select": "^2.0.0", - "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.37", - "csso": "^4.0.2", - "js-yaml": "^3.13.1", - "mkdirp": "~0.5.1", - "object.values": "^1.1.0", - "sax": "~1.2.4", - "stable": "^0.1.8", - "unquote": "~1.1.1", - "util.promisify": "~1.0.0" }, - "dependencies": { - "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" - } - }, - "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 - } + "engines": { + "node": ">=4" } }, - "tapable": { + "node_modules/tapable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "tar-stream": { + "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, - "requires": { + "dependencies": { "bl": "^1.0.0", "buffer-alloc": "^1.2.0", "end-of-stream": "^1.0.0", @@ -8513,652 +12126,1032 @@ "readable-stream": "^2.3.0", "to-buffer": "^1.1.1", "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 0.8.0" } }, - "tcp-port-used": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.1.tgz", - "integrity": "sha512-rwi5xJeU6utXoEIiMvVBMc9eJ2/ofzB+7nLOdnZuFTmNCLqRiQh2sMG9MqCxHU/69VC/Fwp5dV9306Qd54ll1Q==", - "dev": true, - "requires": { - "debug": "4.1.0", - "is2": "2.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz", - "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } + "node_modules/tcp-port-used": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.2.tgz", + "integrity": "sha512-l7ar8lLUD3XS1V2lfoJlCBaeoaWo/2xfYt81hM7VlvR4RrMVFqfmzfhLVk40hAb368uitje5gPtBRL1m/DGvLA==", + "dev": true, + "dependencies": { + "debug": "4.3.1", + "is2": "^2.0.6" } }, - "temp-dir": { + "node_modules/temp-dir": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", - "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=", - "dev": true + "integrity": "sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ==", + "dev": true, + "engines": { + "node": ">=4" + } }, - "tempfile": { + "node_modules/tempfile": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/tempfile/-/tempfile-2.0.0.tgz", - "integrity": "sha1-awRGhWqbERTRhW/8vlCczLCXcmU=", + "integrity": "sha512-ZOn6nJUgvgC09+doCEF3oB+r3ag7kUvlsXEGX069QRD60p+P3uP7XG9N2/at+EyIRGSN//ZY3LyEotA1YpmjuA==", "dev": true, - "requires": { + "dependencies": { "temp-dir": "^1.0.0", "uuid": "^3.0.1" + }, + "engines": { + "node": ">=4" } }, - "text-table": { + "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "through": { + "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, - "through2": { + "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, - "requires": { + "dependencies": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" } }, - "timed-out": { + "node_modules/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 + "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "timsort": { + "node_modules/timsort": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", + "integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==", "dev": true }, - "tiny-emitter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", - "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", - "dev": true, - "optional": true - }, - "tiny-lr": { + "node_modules/tiny-lr": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", "integrity": "sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==", "dev": true, - "requires": { + "dependencies": { "body": "^5.1.0", "debug": "^3.1.0", "faye-websocket": "~0.10.0", "livereload-js": "^2.3.0", "object-assign": "^4.1.0", "qs": "^6.4.0" + } + }, + "node_modules/tiny-lr/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/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==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "faye-websocket": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", - "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - } + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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, + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/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, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.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==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/toml": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/toml/-/toml-2.3.6.tgz", + "integrity": "sha512-gVweAectJU3ebq//Ferr2JUY4WKSDe5N+z0FvjDncLGyHmIDoxgY/2Ie4qfEIDm4IS7OA6Rmdm7pdEEdMcV/xQ==", + "dev": true + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/tree-node-cli": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/tree-node-cli/-/tree-node-cli-1.6.0.tgz", + "integrity": "sha512-M8um5Lbl76rWU5aC8oOeEhruiCM29lFCKnwpxrwMjpRicHXJx+bb9Cak11G3zYLrMb6Glsrhnn90rHIzDJrjvg==", + "dev": true, + "dependencies": { + "commander": "^5.0.0", + "fast-folder-size": "1.6.1", + "pretty-bytes": "^5.6.0" + }, + "bin": { + "tree": "bin/tree.js", + "treee": "bin/tree.js" + } + }, + "node_modules/tree-node-cli/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/trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha512-Nm4cF79FhSTzrLKGDMi3I4utBtFv8qKy4sq1enftf2gMdpqI8oVQTAfySkTz5r49giVzDj88SVZXP4CeYQwjaw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/trim-repeated/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/truncate-html": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/truncate-html/-/truncate-html-1.0.4.tgz", + "integrity": "sha512-FpDAlPzpJ3jlZiNEahRs584FS3jOSQafgj4cC9DmAYPct6uMZDLY625+eErRd43G35vGDrNq3i7b4aYUQ/Bxqw==", + "dev": true, + "dependencies": { + "@types/cheerio": "^0.22.8", + "cheerio": "0.22.0" } }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "node_modules/truncate-html/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, - "requires": { - "os-tmpdir": "~1.0.2" + "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" } }, - "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 - }, - "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=", + "node_modules/truncate-html/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, - "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, - "requires": { - "is-buffer": "^1.1.5" - } - } + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" } }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "node_modules/truncate-html/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, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" + "engines": { + "node": "*" } }, - "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=", + "node_modules/truncate-html/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, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "dependencies": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" } }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "dev": true - }, - "toml": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/toml/-/toml-2.3.6.tgz", - "integrity": "sha512-gVweAectJU3ebq//Ferr2JUY4WKSDe5N+z0FvjDncLGyHmIDoxgY/2Ie4qfEIDm4IS7OA6Rmdm7pdEEdMcV/xQ==", + "node_modules/truncate-html/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 }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "node_modules/truncate-html/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, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" + "dependencies": { + "domelementtype": "1" } }, - "tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "node_modules/truncate-html/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, - "requires": { - "punycode": "^2.1.0" + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" } }, - "tree-node-cli": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/tree-node-cli/-/tree-node-cli-1.4.0.tgz", - "integrity": "sha512-hBc/cp7rTSHFSFvaTzmHNYyJv87UJBsxsfCoq2DtDQuMES4vhnLuvXZit/asGtZG8edWTCydWeFWoBz9LYkJdQ==", + "node_modules/truncate-html/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/truncate-html/node_modules/htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", "dev": true, - "requires": { - "commander": "^5.0.0" - }, "dependencies": { - "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 - } + "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" } }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "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=", + "node_modules/truncate-html/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, - "requires": { - "escape-string-regexp": "^1.0.2" - }, "dependencies": { - "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 - } + "boolbase": "~1.0.0" } }, - "truncate-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/truncate-html/-/truncate-html-1.0.3.tgz", - "integrity": "sha512-1o1prdRv+iehXcGwn29YgXU17DotHkr+OK3ijVEG7FGMwHNG9RyobXwimw6djDvbIc24rhmz3tjNNvNESjkNkQ==", + "node_modules/truncate-html/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, - "requires": { - "@types/cheerio": "^0.22.8", - "cheerio": "0.22.0" + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" } }, - "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "node_modules/tslib": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", "dev": true }, - "tunnel-agent": { + "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "dev": true, - "requires": { + "dependencies": { "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" } }, - "tweetnacl": { + "node_modules/tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", "dev": true }, - "type-is": { + "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==", "dev": true, - "requires": { + "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "typedarray": { + "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "dev": true }, - "unbzip2-stream": { + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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, - "requires": { + "dependencies": { "buffer": "^5.2.1", "through": "^2.3.8" } }, - "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==", - "dev": true + "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" + } }, - "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==", + "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, - "requires": { - "unicode-canonical-property-names-ecmascript": "^1.0.4", - "unicode-property-aliases-ecmascript": "^1.0.4" + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" } }, - "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==", - "dev": true + "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" + } }, - "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==", - "dev": true + "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" + } }, - "union-value": { + "node_modules/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, - "requires": { + "dependencies": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "uniq": { + "node_modules/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 }, - "uniqs": { + "node_modules/uniqs": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", - "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", + "integrity": "sha512-mZdDpf3vBV5Efh29kMw5tXoup/buMgxLzOt/XKFKcVmi+15ManNQWr6HfZ2aiZTYlYixbdNJ0KFmIZIv52tHSQ==", "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==", - "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" + } }, - "unpipe": { + "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } }, - "unquote": { + "node_modules/unquote": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", - "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=", + "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==", "dev": true }, - "unset-value": { + "node_modules/unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", "dev": true, - "requires": { + "dependencies": { "has-value": "^0.3.1", "isobject": "^3.0.0" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", + "dev": true, + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", + "dev": true, + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unzipper": { + "version": "0.10.11", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz", + "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==", + "dev": true, "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, - "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, - "requires": { - "isarray": "1.0.0" - } - } - } + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "^1.0.12", + "graceful-fs": "^4.2.2", + "listenercount": "~1.0.1", + "readable-stream": "~2.3.6", + "setimmediate": "~1.0.4" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" }, - "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 + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "node_modules/update-browserslist-db/node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "requires": { + "dependencies": { "punycode": "^2.1.0" } }, - "urix": { + "node_modules/urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", + "deprecated": "Please see https://github.com/lydell/urix#deprecated", "dev": true }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "url-parse-lax": { + "node_modules/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=", + "integrity": "sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==", "dev": true, - "requires": { + "dependencies": { "prepend-http": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "url-to-options": { + "node_modules/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 + "integrity": "sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==", + "dev": true, + "engines": { + "node": ">= 4" + } }, - "use": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "util-deprecate": { + "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, - "util.promisify": { + "node_modules/util.promisify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", "dev": true, - "requires": { + "dependencies": { "define-properties": "^1.1.3", "es-abstract": "^1.17.2", "has-symbols": "^1.0.1", "object.getownpropertydescriptors": "^2.1.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "utils-merge": { + "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } }, - "uuid": { + "node_modules/uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true + "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.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } }, - "validate-npm-package-license": { + "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, - "requires": { + "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, - "vary": { + "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } }, - "vendors": { + "node_modules/vendors": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", - "dev": true + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, - "verror": { + "node_modules/verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", "dev": true, - "requires": { + "engines": [ + "node >=0.6.0" + ], + "dependencies": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" } }, - "webidl-conversions": { + "node_modules/webidl-conversions": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", "dev": true }, - "websocket-driver": { + "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==", "dev": true, - "requires": { + "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" } }, - "websocket-extensions": { + "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==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.8.0" + } }, - "whatwg-url": { + "node_modules/whatwg-url": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", "dev": true, - "requires": { + "dependencies": { "lodash.sortby": "^4.7.0", "tr46": "^1.0.1", "webidl-conversions": "^4.0.2" } }, - "which": { + "node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, - "requires": { + "dependencies": { "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", + "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "wordwrap": { + "node_modules/wordwrap": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", - "dev": true + "integrity": "sha512-xSBsCeh+g+dinoBv3GAOWM4LcVVO68wLXRanibtBSdUvkGWQRGeE9P7IwU9EmDDi4jA6L44lz15CGMwdw9N5+Q==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } }, - "worker-rpc": { + "node_modules/worker-rpc": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/worker-rpc/-/worker-rpc-0.1.1.tgz", "integrity": "sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg==", "dev": true, - "requires": { + "dependencies": { "microevent.ts": "~0.1.1" } }, - "wrappy": { + "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, - "xml-js": { + "node_modules/xml-js": { "version": "1.6.11", "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", "dev": true, - "requires": { + "dependencies": { "sax": "^1.2.4" + }, + "bin": { + "xml-js": "bin/cli.js" } }, - "xmlbuilder": { + "node_modules/xmlbuilder": { "version": "13.0.2", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-13.0.2.tgz", "integrity": "sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=6.0" + } }, - "xtend": { + "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.4" + } }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, - "yamljs": { + "node_modules/yamljs": { "version": "0.2.10", "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.2.10.tgz", - "integrity": "sha1-SBzHwlynOvWfWR8MluPOVsdXpA8=", + "integrity": "sha512-sbkbOosewjeRmJ23Hjee1RgTxn+xa7mt4sew3tfD0SdH0LTcswnZC9dhSNq4PIz15roQMzb84DjECyQo5DWIww==", "dev": true, - "requires": { + "dependencies": { "argparse": "^1.0.7", "glob": "^7.0.5" + }, + "bin": { + "json2yaml": "bin/json2yaml", + "yaml2json": "bin/yaml2json" } }, - "yargs": { + "node_modules/yargs": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-2.3.0.tgz", - "integrity": "sha1-6QDIclDsXNCA22AJ/j3WMVbx1/s=", + "integrity": "sha512-w48USdbTdaVMcE3CnXsEtSY9zYSN7dTyVnLBgrJF2quA5rLwobC9zixxfexereLGFaxjxtR3oWdydC0qoayakw==", "dev": true, - "requires": { + "dependencies": { "wordwrap": "0.0.2" } }, - "yauzl": { + "node_modules/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": { + "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } diff --git a/website/package.json b/website/package.json index b7123cda6..117aeba83 100644 --- a/website/package.json +++ b/website/package.json @@ -1,13 +1,15 @@ { "private": true, "scripts": { - "start": "docusaurus-start", - "build": "docusaurus-build", - "publish-gh-pages": "docusaurus-publish", - "version": "docusaurus-version", - "rename-version": "docusaurus-rename-version" + "build": "npx docusaurus-build", + "prenew-release": "npm run --prefix ../ gen:docs -- --ref v$npm_config_release", + "new-release": "npx docusaurus-version $npm_config_release", + "postnew-release": "git restore ../docs", + "publish-gh-pages": "npx docusaurus-publish", + "rename-version": "npx docusaurus-rename-version", + "start": "npx docusaurus-start" }, "devDependencies": { - "docusaurus": "^1.14.6" + "docusaurus": "^1.14.7" } } diff --git a/website/pages/en/help.js b/website/pages/en/help.js index 864c2a47f..e5c373b38 100644 --- a/website/pages/en/help.js +++ b/website/pages/en/help.js @@ -5,29 +5,28 @@ * LICENSE file in the root directory of this source tree. */ -const React = require('react'); +const React = require("react"); -const CompLibrary = require('../../core/CompLibrary.js'); +const CompLibrary = require("../../core/CompLibrary.js"); const Container = CompLibrary.Container; const GridBlock = CompLibrary.GridBlock; -const siteConfig = require(process.cwd() + '/siteConfig.js'); +const siteConfig = require(process.cwd() + "/siteConfig.js"); class Help extends React.Component { render() { const supportLinks = [ { - content: - 'Learn more using the [documentation on this site.](/test-site/docs/en/doc1.html)', - title: 'Browse Docs', + content: "Learn more using the [documentation on this site.](/test-site/docs/en/doc1.html)", + title: "Browse Docs", }, { - content: 'Ask questions about the documentation and project', - title: 'Join the community', + content: "Ask questions about the documentation and project", + title: "Join the community", }, { content: "Find out what's new with this project", - title: 'Stay up to date', + title: "Stay up to date", }, ]; diff --git a/website/pages/en/index.js b/website/pages/en/index.js index 80d767e2d..53a4a6bde 100644 --- a/website/pages/en/index.js +++ b/website/pages/en/index.js @@ -247,19 +247,6 @@ const CollectiveSection = props => ( diff --git a/website/pages/en/users.js b/website/pages/en/users.js index f359cc5b3..e61bffab5 100644 --- a/website/pages/en/users.js +++ b/website/pages/en/users.js @@ -5,12 +5,12 @@ * LICENSE file in the root directory of this source tree. */ -const React = require('react'); +const React = require("react"); -const CompLibrary = require('../../core/CompLibrary.js'); +const CompLibrary = require("../../core/CompLibrary.js"); const Container = CompLibrary.Container; -const siteConfig = require(process.cwd() + '/siteConfig.js'); +const siteConfig = require(process.cwd() + "/siteConfig.js"); class Users extends React.Component { render() { @@ -27,7 +27,7 @@ class Users extends React.Component { return (
- +

Who's Using This?

@@ -37,7 +37,8 @@ class Users extends React.Component {

Are you using this project?

+ className="button" + > Add your company
diff --git a/website/pages/en/versions.js b/website/pages/en/versions.js index fc9f6938c..3230e8686 100644 --- a/website/pages/en/versions.js +++ b/website/pages/en/versions.js @@ -75,9 +75,7 @@ function Versions(props) { {version} Documentation diff --git a/website/pages/snippets/object-type.md b/website/pages/snippets/object-type.md index 7317bf62e..c1031b628 100644 --- a/website/pages/snippets/object-type.md +++ b/website/pages/snippets/object-type.md @@ -1,4 +1,6 @@ -```typescript + + +```ts @ObjectType() class Recipe { @Field() diff --git a/website/pages/snippets/testability.md b/website/pages/snippets/testability.md index 591d74ba1..cd14d561b 100644 --- a/website/pages/snippets/testability.md +++ b/website/pages/snippets/testability.md @@ -1,4 +1,6 @@ -```typescript + + +```ts @Resolver(of => Recipe) export class RecipeResolver { constructor( diff --git a/website/pages/snippets/typeorm.md b/website/pages/snippets/typeorm.md index 4b5673fe1..1e447f075 100644 --- a/website/pages/snippets/typeorm.md +++ b/website/pages/snippets/typeorm.md @@ -1,4 +1,6 @@ -```typescript + + +```ts @Entity() @ObjectType() export class Rate { @@ -17,7 +19,7 @@ export class Rate { @CreateDateColumn() date: Date; - @ManyToOne(type => Recipe) + @ManyToOne(type => Recipe) recipe: Promise; } ``` diff --git a/website/pages/snippets/validation.md b/website/pages/snippets/validation.md index 912f5738a..e50035247 100644 --- a/website/pages/snippets/validation.md +++ b/website/pages/snippets/validation.md @@ -1,11 +1,13 @@ -```typescript + + +```ts @InputType() export class RecipeInput { @Field() @MaxLength(30) title: string; - @Field({ nullable: true }) + @Field({ nullable: true }) @Length(30, 255) description?: string; diff --git a/website/sidebars.json b/website/sidebars.json index 8490ec531..3e173f2c0 100644 --- a/website/sidebars.json +++ b/website/sidebars.json @@ -6,8 +6,10 @@ "getting-started", "types-and-fields", "resolvers", - "bootstrap" + "bootstrap", + "esm" ], + "Migration guide": ["migration-guide"], "Advanced guides": [ "scalars", "enums", @@ -28,7 +30,8 @@ "complexity" ], "Integrations": ["prisma", "nestjs"], - "Others": ["emit-schema", "performance", "browser-usage"] + "Others": ["emit-schema", "performance"], + "Recipes": ["browser-usage", "aws-lambda"] }, "examples": { "Examples": ["examples"] diff --git a/website/static/css/prism-theme.css b/website/static/css/prism-theme.css index bbe3d25d2..80a3116b3 100644 --- a/website/static/css/prism-theme.css +++ b/website/static/css/prism-theme.css @@ -6,15 +6,20 @@ code { color: #dcdcaa; } -.token.punctuation, .token.operator, .token.constant, .hljs.graphql { +.token.punctuation, +.token.operator, +.token.constant, +.hljs.graphql { color: #d4d4d4; } -.token.keyword, .token.boolean { +.token.keyword, +.token.boolean { color: #569cd6; } -.token.class-name, .token.builtin { +.token.class-name, +.token.builtin { color: #4ec9b0; } @@ -34,7 +39,9 @@ code { color: #d16969; } -.hljs, .token.attr-name, .token.property { +.hljs, +.token.attr-name, +.token.property { color: #9cdcfe; } diff --git a/website/static/img/admin-remix.png b/website/static/img/admin-remix.png new file mode 100644 index 000000000..8d4d799bf Binary files /dev/null and b/website/static/img/admin-remix.png differ diff --git a/website/static/img/casinodeps.svg b/website/static/img/casinodeps.svg new file mode 100644 index 000000000..92083ec06 --- /dev/null +++ b/website/static/img/casinodeps.svg @@ -0,0 +1 @@ +Asset 3 \ No newline at end of file diff --git a/website/static/img/ecad_new.png b/website/static/img/ecad_new.png new file mode 100644 index 000000000..0efd15ad2 Binary files /dev/null and b/website/static/img/ecad_new.png differ diff --git a/website/static/img/flatirons.png b/website/static/img/flatirons.png new file mode 100644 index 000000000..4ef35ebc9 Binary files /dev/null and b/website/static/img/flatirons.png differ diff --git a/website/static/img/github-sponsors.svg b/website/static/img/github-sponsors.svg new file mode 100644 index 000000000..d44844487 --- /dev/null +++ b/website/static/img/github-sponsors.svg @@ -0,0 +1,130 @@ + + + + +Bronze Sponsors πŸ₯‰ + Jan-Henrik + +Members πŸ’ͺ + + +Backers β˜• + + + + + + + + + + +Past Sponsors ⏳ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/static/img/instinctools.svg b/website/static/img/instinctools.svg new file mode 100644 index 000000000..05db3a239 --- /dev/null +++ b/website/static/img/instinctools.svg @@ -0,0 +1,14 @@ + + + + background + + + + Layer 1 + + + + + + \ No newline at end of file diff --git a/website/static/img/intexsoft.jpg b/website/static/img/intexsoft.jpg new file mode 100644 index 000000000..21128a138 Binary files /dev/null and b/website/static/img/intexsoft.jpg differ diff --git a/website/static/img/lovd.png b/website/static/img/lovd.png new file mode 100644 index 000000000..38315c424 Binary files /dev/null and b/website/static/img/lovd.png differ diff --git a/website/static/img/non-gamstop-casinos.svg b/website/static/img/non-gamstop-casinos.svg new file mode 100644 index 000000000..35cdfb8d7 --- /dev/null +++ b/website/static/img/non-gamstop-casinos.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/static/img/non-stop-casino.png b/website/static/img/non-stop-casino.png new file mode 100644 index 000000000..84aace8d6 Binary files /dev/null and b/website/static/img/non-stop-casino.png differ diff --git a/website/static/img/nongamstopbets.png b/website/static/img/nongamstopbets.png new file mode 100644 index 000000000..08e3b6159 Binary files /dev/null and b/website/static/img/nongamstopbets.png differ diff --git a/website/static/img/pwmlogo.png b/website/static/img/pwmlogo.png new file mode 100644 index 000000000..356c50346 Binary files /dev/null and b/website/static/img/pwmlogo.png differ diff --git a/website/static/img/qulix.png b/website/static/img/qulix.png new file mode 100644 index 000000000..e13133595 Binary files /dev/null and b/website/static/img/qulix.png differ diff --git a/website/static/img/rubydroid.svg b/website/static/img/rubydroid.svg new file mode 100644 index 000000000..a23560844 --- /dev/null +++ b/website/static/img/rubydroid.svg @@ -0,0 +1,24 @@ + + + + F8DCB9AC-40FA-4ADB-8604-6311CFC9450D-416-0000F5A4C92BF4F5 + Created with sketchtool. + + + + + + + + + + + \ No newline at end of file diff --git a/website/static/img/slon.png b/website/static/img/slon.png new file mode 100644 index 000000000..2a8bb349f Binary files /dev/null and b/website/static/img/slon.png differ diff --git a/website/static/img/vps-server.png b/website/static/img/vps-server.png new file mode 100644 index 000000000..60ca38537 Binary files /dev/null and b/website/static/img/vps-server.png differ diff --git a/website/versioned_docs/version-0.16.0/authorization.md b/website/versioned_docs/version-0.16.0/authorization.md index 2c202f027..02dacd508 100644 --- a/website/versioned_docs/version-0.16.0/authorization.md +++ b/website/versioned_docs/version-0.16.0/authorization.md @@ -11,8 +11,10 @@ In express.js (and other Node.js framework) we use middlewares for this, like `p And that's why authorization is a first-class feature in `TypeGraphQL`! ## How to use? + At first, you need to use `@Authorized` decorator as a guard on a field or a query/mutation. Example object type's fields guards: + ```typescript @ObjectType() class MyObject { @@ -39,6 +41,7 @@ By default the roles are `string` but you can change it easily as the decorator This way authed users (regardless of theirs roles) could read only `publicField` or `authorizedField` from `MyObject` object. They will receive `null` when accessing `hiddenField` field and will receive error (that will propagate through the whole query tree looking for nullable field) for `adminField` when they don't satisfy roles constraints. Sample query and mutations guards: + ```typescript @Resolver() class MyResolver { @@ -64,22 +67,28 @@ class MyResolver { } } ``` + Authed users (regardless of theirs roles) will be able to read data from `publicQuery` and `authedQuery` but will receive error trying to perform `adminMutation` when their roles doesn't include `ADMIN` or `MODERATOR`. In next step, you need to create your auth checker function. Its implementation may depends on your business logic: -```typescript -export const customAuthChecker: AuthChecker = - ({ root, args, context, info }, roles) => { - // here you can read user from context - // and check his permission in db against `roles` argument - // that comes from `@Authorized`, eg. ["ADMIN", "MODERATOR"] - return true; // or false if access denied - } +```typescript +export const customAuthChecker: AuthChecker = ( + { root, args, context, info }, + roles, +) => { + // here you can read user from context + // and check his permission in db against `roles` argument + // that comes from `@Authorized`, eg. ["ADMIN", "MODERATOR"] + + return true; // or false if access denied +}; ``` + The second argument of `AuthChecker` generic type is `RoleType` - use it together with `@Authorized` decorator generic type. The last step is to register the function while building the schema: + ```typescript import { customAuthChecker } from "../auth/custom-auth-checker.ts"; @@ -87,26 +96,29 @@ const schema = await buildSchema({ resolvers: [MyResolver], // here we register the auth checking function // or defining it inline - authChecker: customAuthChecker, -}) + authChecker: customAuthChecker, +}); ``` + And it's done! πŸ˜‰ If you need silent auth guards and you don't want to return auth errors to users, you can set `authMode` property of `buildSchema` config object to `"null"`: + ```typescript const schema = await buildSchema({ resolvers: ["./**/*.resolver.ts"], - authChecker: customAuthChecker, + authChecker: customAuthChecker, authMode: "null", -}) +}); ``` + It will then return `null` instead of throwing authorization error. ## Recipes You can also use `TypeGraphQL` with JWT authentication. Example using `apollo-server-express`: -```typescript +```typescript import express from "express"; import { ApolloServer, gql } from "apollo-server-express"; import * as jwt from "express-jwt"; @@ -114,10 +126,10 @@ import * as jwt from "express-jwt"; import { schema } from "../example/above"; const app = express(); -const path = '/graphql'; +const path = "/graphql"; // Create a GraphQL server -const server = new ApolloServer({ +const server = new ApolloServer({ schema, context: ({ req }) => { const context = { @@ -129,20 +141,25 @@ const server = new ApolloServer({ }); // Mount a jwt or other authentication middleware that is run before the GraphQL execution -app.use(path, jwt({ - secret: "TypeGraphQL", - credentialsRequired: false, -})); +app.use( + path, + jwt({ + secret: "TypeGraphQL", + credentialsRequired: false, + }), +); // Apply the GraphQL server middleware server.applyMiddleware({ app, path }); -// Launch the express server +// Launch the express server app.listen({ port: 4000 }, () => - console.log(`πŸš€ Server ready at http://localhost:4000${server.graphqlPath}`) -) + console.log(`πŸš€ Server ready at http://localhost:4000${server.graphqlPath}`), +); ``` + Then you can use standard, token based authorization in HTTP header like in classic REST API and take advantages of `TypeGraphQL` authorization mechanism. ## Example -You can see how this works together in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/master/examples/authorization). + +You can see how this works together in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/authorization). diff --git a/website/versioned_docs/version-0.16.0/bootstrap.md b/website/versioned_docs/version-0.16.0/bootstrap.md index 8ae0beec5..326303ea2 100644 --- a/website/versioned_docs/version-0.16.0/bootstrap.md +++ b/website/versioned_docs/version-0.16.0/bootstrap.md @@ -26,10 +26,7 @@ So you can also provide an array of paths to resolver module files instead, whic ```typescript const schema = await buildSchema({ - resolvers: [ - __dirname + "/modules/**/*.resolver.ts", - __dirname + "/resolvers/**/*.ts", - ], + resolvers: [__dirname + "/modules/**/*.resolver.ts", __dirname + "/resolvers/**/*.ts"], }); ``` @@ -53,7 +50,7 @@ bootstrap(); // actually run the async function ## Create HTTP GraphQL endpoint -In most cases, the GraphQL app is served by a HTTP server. After building the schema we can create the GraphQL endpoint with a variety of tools such as [`graphql-yoga`](https://github.com/prisma/graphql-yoga) or [`apollo-server`](https://github.com/apollographql/apollo-server). Here is an example using [`apollo-server`](https://github.com/apollographql/apollo-server): +In most cases, the GraphQL app is served by a HTTP server. After building the schema we can create the GraphQL endpoint with a variety of tools such as [`graphql-yoga`](https://github.com/prisma/graphql-yoga) or [`apollo-server`](https://github.com/apollographql/apollo-server). Here is an example using [`apollo-server`](https://github.com/apollographql/apollo-server): ```typescript import { ApolloServer } from "apollo-server"; @@ -64,7 +61,7 @@ async function bootstrap() { // ... Building schema here // Create GraphQL server - const server = new ApolloServer({ + const server = new ApolloServer({ schema, playground: true, }); diff --git a/website/versioned_docs/version-0.16.0/browser-usage.md b/website/versioned_docs/version-0.16.0/browser-usage.md index 079200648..95969f31c 100644 --- a/website/versioned_docs/version-0.16.0/browser-usage.md +++ b/website/versioned_docs/version-0.16.0/browser-usage.md @@ -5,9 +5,11 @@ original_id: browser-usage --- ## Using classes in client app + Sometimes you might want to use the classes, that you've created and annotated with TypeGraphQL decorators, in your client app that works in browser. For example, you may want to reuse the args or input classes with `class-validator` decorators or the object type classes with some helpful custom methods. As TypeGraphQL is a Node.js framework, it doesn't work in browser environment, so you may quickly got an error, e.g. `ERROR in ./node_modules/fs.realpath/index.js`, while trying to build your app with Webpack. To fix that, you have to configure Webpack to use the decorators shim instead of normal module. All you need is to add this plugin code to your webpack config: + ```js plugins: [ ..., // here any other existing plugins that you already have @@ -18,4 +20,3 @@ plugins: [ ``` Also, thanks to this your bundle will be much lighter as you don't embedded the whole TypeGraphQL library code in your app. - diff --git a/website/versioned_docs/version-0.16.0/complexity.md b/website/versioned_docs/version-0.16.0/complexity.md index e31d873fd..74293c86d 100644 --- a/website/versioned_docs/version-0.16.0/complexity.md +++ b/website/versioned_docs/version-0.16.0/complexity.md @@ -3,81 +3,82 @@ title: Query complexity id: version-0.16.0-complexity original_id: complexity --- -A single GraphQL query can potentially generate huge workload for a server, like thousands of database operations which can be used to cause DDoS attacks. To keep track and limit of what each GraphQL operation can do , `TypeGraphQL` provides you the option of integrating with Query Complexity tools like [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity). +A single GraphQL query can potentially generate huge workload for a server, like thousands of database operations which can be used to cause DDoS attacks. To keep track and limit of what each GraphQL operation can do , `TypeGraphQL` provides you the option of integrating with Query Complexity tools like [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity). The cost analysis-based solution is very promising, since you can define a β€œcost” per field and then analyze the AST to estimate the total cost of the GraphQL query. Of course all the analysis is handled by `graphql-query-complexity` . All you need to do is define your complexity cost for the fields (fields, mutations, subscriptions) in`TypeGraphQL` and implement `graphql-query-complexity` in whatever GraphQL server you have. ## How to use? + At first, you need to pass `complexity` as an option to the decorator on a field/query/mutation. Example of complexity -```typescript +```typescript @ObjectType() class MyObject { @Field({ complexity: 2 }) publicField: string; - @Field({ complexity: ({args, childComplexity}) => childComplexity + 1 }) + @Field({ complexity: ({ args, childComplexity }) => childComplexity + 1 }) complexField: string; } ``` -You can omit the `complexity` option if the complexity value is 1. -You can pass complexity as option to any of `@Field`, `@FieldResolver`, `@Mutation` & `@Subscription`. For the same property, if both the `@Fieldresolver` as well as `@Field` have complexity defined , then the complexity passed to the field resolver decorator takes precedence. +You can omit the `complexity` option if the complexity value is 1. +You can pass complexity as option to any of `@Field`, `@FieldResolver`, `@Mutation` & `@Subscription`. For the same property, if both the `@Fieldresolver` as well as `@Field` have complexity defined , then the complexity passed to the field resolver decorator takes precedence. -In next step, you need to integrate `graphql-query-complexity` with your GraphQL server. +In next step, you need to integrate `graphql-query-complexity` with your GraphQL server. ```typescript - // Create GraphQL server - const server = new GraphQLServer({ schema }); - - // Configure server options - const serverOptions: Options = { - port: 4000, - endpoint: "/graphql", - playground: "/playground", - validationRules: req => [ - queryComplexity({ - // The maximum allowed query complexity, queries above this threshold will be rejected - maximumComplexity: 8, - // The query variables. This is needed because the variables are not available - // in the visitor of the graphql-js library - variables: req.query.variables, - // Optional callback function to retrieve the determined query complexity - // Will be invoked weather the query is rejected or not - // This can be used for logging or to implement rate limiting - onComplete: (complexity: number) => { - console.log("Query Complexity:", complexity); - }, - estimators: [ - // Using fieldConfigEstimator is mandatory to make it work with type-graphql - fieldConfigEstimator(), - // This will assign each field a complexity of 1 if no other estimator - // returned a value. We can define the default value for field not explicitly annotated - simpleEstimator({ - defaultComplexity: 1, - }), - ], - }), - ], - }; - - // Start the server - server.start(serverOptions, ({ port, playground }) => { - console.log( - `Server is running, GraphQL Playground available at http://localhost:${port}${playground}`, - ); - }); +// Create GraphQL server +const server = new GraphQLServer({ schema }); + +// Configure server options +const serverOptions: Options = { + port: 4000, + endpoint: "/graphql", + playground: "/playground", + validationRules: req => [ + queryComplexity({ + // The maximum allowed query complexity, queries above this threshold will be rejected + maximumComplexity: 8, + // The query variables. This is needed because the variables are not available + // in the visitor of the graphql-js library + variables: req.query.variables, + // Optional callback function to retrieve the determined query complexity + // Will be invoked weather the query is rejected or not + // This can be used for logging or to implement rate limiting + onComplete: (complexity: number) => { + console.log("Query Complexity:", complexity); + }, + estimators: [ + // Using fieldConfigEstimator is mandatory to make it work with type-graphql + fieldConfigEstimator(), + // This will assign each field a complexity of 1 if no other estimator + // returned a value. We can define the default value for field not explicitly annotated + simpleEstimator({ + defaultComplexity: 1, + }), + ], + }), + ], +}; + +// Start the server +server.start(serverOptions, ({ port, playground }) => { + console.log( + `Server is running, GraphQL Playground available at http://localhost:${port}${playground}`, + ); +}); ``` And it's done! πŸ˜‰ For more info about how query complexity is computed, please visit[graphql-query-complexity](https://github.com/ivome/graphql-query-complexity). - ## Example -You can see how this works together in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/master/examples/query-complexity). + +You can see how this works together in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/query-complexity). diff --git a/website/versioned_docs/version-0.16.0/dependency-injection.md b/website/versioned_docs/version-0.16.0/dependency-injection.md index 05685281f..8b25d804e 100644 --- a/website/versioned_docs/version-0.16.0/dependency-injection.md +++ b/website/versioned_docs/version-0.16.0/dependency-injection.md @@ -71,7 +71,7 @@ export class RecipeService { ### Example -You can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/master/examples/using-container). +You can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/using-container). ## Scoped containers @@ -142,4 +142,4 @@ The only thing that left is the container configuration - you need to check out ### Example -For more advanced usage example with scoped containers, check out [advanced example with scoped containers](https://github.com/MichalLytek/type-graphql/tree/master/examples/using-scoped-container). +For more advanced usage example with scoped containers, check out [advanced example with scoped containers](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/using-scoped-container). diff --git a/website/versioned_docs/version-0.16.0/enums.md b/website/versioned_docs/version-0.16.0/enums.md index a556fc51a..bdb7844c5 100644 --- a/website/versioned_docs/version-0.16.0/enums.md +++ b/website/versioned_docs/version-0.16.0/enums.md @@ -10,6 +10,7 @@ Enums allow to limit the range of possible variable's values to a set of predefi GraphQL also has enum type support, so `TypeGraphQL` allows you to use TypeScript enums in your GraphQL schema. ## Usage + First of all, you need to create a TypeScript enum. It can be a numeric or string enum - the internal value of enums will be taken from enums definition values and the public names from the enum keys: @@ -73,7 +74,8 @@ class Resolver { case Direction.Right: this.sprite.position.x++; break; - default: // it will never be hitten ;) + default: + // it will never be hitten ;) return false; } diff --git a/website/versioned_docs/version-0.16.0/getting-started.md b/website/versioned_docs/version-0.16.0/getting-started.md index 94d621151..221e96c15 100644 --- a/website/versioned_docs/version-0.16.0/getting-started.md +++ b/website/versioned_docs/version-0.16.0/getting-started.md @@ -9,7 +9,9 @@ To explore all powerful capabilities of TypeGraphQL, we will create a sample Gra Let's start with the `Recipe` type, which is the foundations of our API. ## Types + We want to get equivalent of this type described in SDL: + ```graphql type Recipe { id: ID! @@ -21,6 +23,7 @@ type Recipe { ``` So we create the `Recipe` class with all properties and types: + ```typescript class Recipe { id: string; @@ -32,6 +35,7 @@ class Recipe { ``` Then we decorate the class and its properties with decorators: + ```typescript @ObjectType() class Recipe { @@ -51,6 +55,7 @@ class Recipe { ingredients: string[]; } ``` + The detailed rules when to use `nullable`, `array` and others are described in [fields and types docs](types-and-fields.md). ## Resolvers @@ -103,7 +108,8 @@ The detailed rules when and why we declare `returns => Recipe` functions and oth ## Inputs and arguments -Ok, but what are `NewRecipeInput` and `RecipesArgs`? They are of course classes: +Ok, but what are `NewRecipeInput` and `RecipesArgs`? They are, of course, classes: + ```typescript @InputType() class NewRecipeDataInput { @@ -127,18 +133,21 @@ class RecipesArgs { skip: number = 0; @Field(type => Int) - @Min(1) @Max(50) + @Min(1) + @Max(50) take: number = 25; } - ``` + `@Length`, `@Min` or `@MaxArraySize` are decorators from [`class-validator`](https://github.com/typestack/class-validator) that automatically perform fields validation in TypeGraphQL. ## Building schema + The last step that we have to do is to actually build the schema from TypeGraphQL definition. We use `buildSchema` function for this: + ```typescript const schema = await buildSchema({ - resolvers: [RecipeResolver] + resolvers: [RecipeResolver], }); // ...creating express server or sth @@ -146,6 +155,7 @@ const schema = await buildSchema({ Et voilΓ ! Now we have fully working GraphQL schema! If we print it, we would receive exactly this: + ```graphql type Recipe { id: ID! @@ -170,6 +180,7 @@ type Mutation { ``` ## Want more? + That was only a tip of the iceberg - a very simple example with basic GraphQL types. Do you use interfaces, enums, unions and custom scalars? That's great because TypeGraphQL fully supports them too! There are also more advanced concepts like authorization checker, inheritance support or field resolvers. -If you want to see how it looks in more complicated case, you can go to the [Examples section](examples.md) where you can find e.g. how nice TypeGraphQL integrates with TypeORM. +If you want to see how it looks in more complicated case, you can go to the [Examples section](examples.md) where you can find e.g. how nice TypeGraphQL integrates with TypeORM. diff --git a/website/versioned_docs/version-0.16.0/interfaces-and-inheritance.md b/website/versioned_docs/version-0.16.0/interfaces-and-inheritance.md index 8ed2b6d8c..eb6c8ad6c 100644 --- a/website/versioned_docs/version-0.16.0/interfaces-and-inheritance.md +++ b/website/versioned_docs/version-0.16.0/interfaces-and-inheritance.md @@ -9,9 +9,10 @@ The main idea of TypeGraphQL is to create GraphQL types based on TypeScript clas In object-oriented programming it is common to create interfaces which describes the contract that classes implementing them has to fulfill. We also compose classes using inheritance. Hence TypeGraphQL supports both GraphQL interfaces as well as composing type definitions by extending the classes. ## Interfaces + TypeScript has first class support for interfaces. Unfortunately, they only exist at compile-time, so we can't use them to build GraphQL schema at runtime by using decorators. -Luckily, we can use an abstract class for this purpose. It behaves almost like an interface (can't be "newed", can be implemented by class), it just won't stop developers from implementing a method or initializing a field. But as long as we treat it like an interface, we can safely use it. +Luckily, we can use an abstract class for this purpose. It behaves almost like an interface (can't be "newed", can be implemented by class), it just won't stop developers from implementing a method or initializing a field. But as long as we treat it like an interface, we can safely use it. So, how do you create GraphQL interface definition? We create an abstract class and decorate it with `@InterfaceType()`. The rest is exactly the same as with object types: we use `@Field` to declare the shape of the type: @@ -44,12 +45,14 @@ The only difference is that we have to let TypeGraphQL know that this `ObjectTyp We can also omit the decorators as the GraphQL types will be copied from the interface definition - this way we don't have to maintain two definitions and just rely on TypeScript type checking of correct interface implementation. -Be aware that when your object type is implementing GraphQL interface type, __you have to return an instance of the type class__ in your resolvers. Otherwise, `graphql-js` will not be able to detect the underlying GraphQL type correctly. +Be aware that when your object type is implementing GraphQL interface type, **you have to return an instance of the type class** in your resolvers. Otherwise, `graphql-js` will not be able to detect the underlying GraphQL type correctly. ## Types inheritance + One of the most known principles of software development is DRY - don't repeat yourself - which tells about avoiding redundancy in our code. -While creating GraphQL API, it's a common pattern to have pagination args in resolvers, like `skip` and `take`. So instead of repeating yourself, you can declare it once: +While creating GraphQL API, it's a common pattern to have pagination args in resolvers, like `skip` and `take`. So instead of repeating yourself, you can declare it once: + ```typescript @ArgsType() class PaginationArgs { @@ -62,6 +65,7 @@ class PaginationArgs { ``` and then reuse it everywhere: + ```typescript @ArgsType() class GetTodosArgs extends PaginationArgs { @@ -71,6 +75,7 @@ class GetTodosArgs extends PaginationArgs { ``` This technique also works with input type classes, as well as with object type classes: + ```typescript @ObjectType() class Person { @@ -88,9 +93,11 @@ class Student extends Person { Note that both the subclass and the parent class must be decorated with the same type of decorator, like `@ObjectType()` in the example `Person -> Student` above. Mixing decorator types across parent and child classes is prohibited and might result in schema building error - you can't e.g decorate the subclass with `@ObjectType()` and the parent with `@InputType()`. ## Resolvers inheritance + The special kind of inheritance in TypeGraphQL is a resolver classes inheritance. This pattern allows you to e.g. create a base CRUD resolver class for your resource/entity, so you don't have to repeat the common boilerplate code all the time. As we need to generate unique query/mutation names, we have to create a factory function for our base class: + ```typescript function createBaseResolver() { abstract class BaseResolver {} @@ -98,9 +105,11 @@ function createBaseResolver() { return BaseResolver; } ``` + Be aware that with some `tsconfig.json` settings you might receive `[ts] Return type of exported function has or is using private name 'BaseResolver'` error - in that case you might need to use `any` as a return type or create a separate class/interface describing the class methods and properties. This factory should take a parameter that we can use to generate queries/mutations names, as well as the type that we would return from the resolvers: + ```typescript function createBaseResolver(suffix: string, objectTypeCls: T) { abstract class BaseResolver {} @@ -110,6 +119,7 @@ function createBaseResolver(suffix: string, objectTypeCls: ``` It's very important to mark the `BaseResolver` class using `@Resolver` decorator with `{ isAbstract: true }` option that will prevent throwing error due to registering multiple queries/mutations with the same name. + ```typescript function createBaseResolver(suffix: string, objectTypeCls: T) { @Resolver({ isAbstract: true }) @@ -120,6 +130,7 @@ function createBaseResolver(suffix: string, objectTypeCls: ``` Then we can implement the resolvers methods in the same way as always. The only difference is that we can use `name` decorator option for `@Query`, `@Mutation` and `@Subscription` decorators to overwrite the name that will be emitted in schema: + ```typescript function createBaseResolver(suffix: string, objectTypeCls: T) { @Resolver({ isAbstract: true }) @@ -127,9 +138,7 @@ function createBaseResolver(suffix: string, objectTypeCls: protected items: T[] = []; @Query(type => [objectTypeCls], { name: `getAll${suffix}` }) - async getAll( - @Arg("first", type => Int) first: number, - ): Promise { + async getAll(@Arg("first", type => Int) first: number): Promise { return this.items.slice(0, first); } } @@ -139,6 +148,7 @@ function createBaseResolver(suffix: string, objectTypeCls: ``` After that we can create a specific resolver class that will extend the base resolver class: + ```typescript const PersonBaseResolver = createBaseResolver("person", Person); @@ -149,6 +159,7 @@ export class PersonResolver extends PersonBaseResolver { ``` We can also add specific queries and mutation in our resolver class, just like always: + ```typescript const PersonBaseResolver = createBaseResolver("person", Person); @@ -161,11 +172,13 @@ export class PersonResolver extends PersonBaseResolver { } } ``` + And that's it! We just need to normally register `PersonResolver` in `buildSchema` and the extended resolver will be working correctly. Be aware that if you want to overwrite the query/mutation/subscription from parent resolver class, you need to generate the same schema name (using `name` decorator option or the class method name). It will overwrite the implementation along with GraphQL args and return types. If you only provide different implementation of the inherited method like `getOne`, it won't work. ## Examples -More advanced usage example of interfaces and types inheritance (e.g. with query returning interface type) you can see in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/master/examples/interfaces-inheritance). -For more advanced resolvers inheritance example, please go to [the example folder](https://github.com/MichalLytek/type-graphql/tree/master/examples/resolvers-inheritance). +More advanced usage example of interfaces and types inheritance (e.g. with query returning interface type) you can see in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/interfaces-inheritance). + +For more advanced resolvers inheritance example, please go to [the example folder](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/resolvers-inheritance). diff --git a/website/versioned_docs/version-0.16.0/introduction.md b/website/versioned_docs/version-0.16.0/introduction.md index 7e13f5938..16dbdaaeb 100644 --- a/website/versioned_docs/version-0.16.0/introduction.md +++ b/website/versioned_docs/version-0.16.0/introduction.md @@ -5,11 +5,13 @@ id: version-0.16.0-introduction original_id: introduction --- -We all love GraphQL! It's so great and solves many problems that we have with REST API, such as overfetching and underfetching. But developing a GraphQL API in Node.js with TypeScript is sometimes a bit of a pain. +We all love GraphQL! It's so great and solves many problems that we have with REST API, such as overfetching and underfetching. But developing a GraphQL API in Node.js with TypeScript is sometimes a bit of a pain. ## What? + **TypeGraphQL** is a library that makes this process enjoyable, by defining the schema using only classes and a bit of decorators magic. Example object type: + ```typescript @ObjectType() class Recipe { @@ -27,17 +29,21 @@ class Recipe { It also has a set of useful features, like validation, authorization and dependency injection, which helps develop GraphQL API quickly & easily! ## Why? + As I mentioned, developing a GraphQL API in Node.js with TypeScript is sometimes a bit of a pain. Why? Let's take a look at the steps we usually have to make. First, we create all the schema types in SDL. We also create our data models using [ORM classes](https://github.com/typeorm/typeorm), which represents our db entities. Then we start to write resolvers for our queries, mutations and fields. This forces us, however, to begin with creating TS interfaces for all arguments and inputs and/or object types. After that, we can actually implement the resolvers, using weird generic signatures, e.g.: + ```typescript -export const recipesResolver: GraphQLFieldResolver = - async (_, args) => { - // our business logic, e.g.: - const repository = getRepository(Recipe); - return repository.find(); - } +export const recipesResolver: GraphQLFieldResolver = async ( + _, + args, +) => { + // our business logic, e.g.: + const repository = getRepository(Recipe); + return repository.find(); +}; ``` The biggest problem is the redundancy in our codebase which makes it difficult to keep things in sync. To add a new field to our entity, we have to jump through all the files: modify entity class, then modify part of the schema, and finally update the interface. The same goes with inputs or arguments: it's easy to forget to update one or make a mistake with the type. Also, what if we've made a typo in field name? The rename feature (F2) won't work correctly. diff --git a/website/versioned_docs/version-0.16.0/middlewares.md b/website/versioned_docs/version-0.16.0/middlewares.md index eec7936ad..c5a07a95e 100644 --- a/website/versioned_docs/version-0.16.0/middlewares.md +++ b/website/versioned_docs/version-0.16.0/middlewares.md @@ -12,8 +12,8 @@ Middlewares are a piece of reusable code that can be easily attached to resolver Middlewares are a very powerful but also a bit complicated feature. Basically, they are functions that take 2 arguments: -* resolver data - the same as for resolvers (`root`, `args`, `context`, `info`) -* `next` function - used to control execution of next middlewares and the resolver to which they are attached +- resolver data - the same as for resolvers (`root`, `args`, `context`, `info`) +- `next` function - used to control execution of next middlewares and the resolver to which they are attached You might be familiar with how middlewares works in [`express.js`](https://expressjs.com/en/guide/writing-middleware.html) but TypeGraphQL middlewares are inspired by the [`koa.js` ones](http://koajs.com/#application). The difference is that the `next` function returns a promise of the value of further middlewares stack and resolver execution. @@ -183,6 +183,7 @@ const schema = await buildSchema({ ### Custom decorators If you want to have a more descriptive and declarative API, you can also create custom decorators. They work in the same way like the reusable middleware function, however in this case you need to return the `UseMiddleware` decorator function: + ```typescript export function ValidateArgs(schema: Schema) { return UseMiddleware(async ({ args }, next) => { @@ -194,6 +195,7 @@ export function ValidateArgs(schema: Schema) { ``` The usage is then very simple, as you have a custom, descriptive decorator - just place it above resolver/field and pass the required arguments to id: + ```typescript @Resolver() export class RecipeResolver { diff --git a/website/versioned_docs/version-0.16.0/resolvers.md b/website/versioned_docs/version-0.16.0/resolvers.md index 1953d294d..40373fd7d 100644 --- a/website/versioned_docs/version-0.16.0/resolvers.md +++ b/website/versioned_docs/version-0.16.0/resolvers.md @@ -9,15 +9,16 @@ Besides [declaring GraphQL's object types](types-and-fields.md), TypeGraphQL all ## Queries and mutations ### Resolvers classes + First you have to create a resolver class and annotate it with `@Resolver()` decorator. This class will behave like a controller from classic REST frameworks: + ```typescript @Resolver() -class RecipeResolver { - -} +class RecipeResolver {} ``` You can use a DI framework (as described in [dependency injection docs](dependency-injection.md)) to inject class dependencies (like services or repositories) or store data inside resolvers class - it's guaranteed to be a single instance per app. + ```typescript @Resolver() class RecipeResolver { @@ -26,6 +27,7 @@ class RecipeResolver { ``` Then you can create class methods which will handle queries and mutations. For example let's add the `recipes` query to return a collection of all recipes: + ```typescript @Resolver() class RecipeResolver { @@ -40,7 +42,8 @@ class RecipeResolver { We also need to do two things. The first is to add the `@Query` decorator, which marks the class method as a GraphQL query. -The second is to provide the return type. Since the method is async, the reflection metadata system shows the return type as `Promise`, so we have to add the decorator's parameter as `returns => [Recipe]` to declare it resolve to an array of `Recipe` object types. +The second is to provide the return type. Since the method is async, the reflection metadata system shows the return type as `Promise`, so we have to add the decorator's parameter as `returns => [Recipe]` to declare it resolve to an array of `Recipe` object types. + ```typescript @Resolver() class RecipeResolver { @@ -54,9 +57,11 @@ class RecipeResolver { ``` ### Arguments + Usually queries have some arguments - it might be an id of the resource, the search phrase or pagination settings. TypeGraphQL allows you to define the arguments in two ways. First is the inline method using `@Arg()` decorator. The drawback is the need of repeating argument name (due to a reflection system limitation) in the decorator parameter. As you can see below, you can also pass a `defaultValue` options that will be reflected in the GraphQL schema. + ```typescript @Resolver() class RecipeResolver { @@ -70,7 +75,9 @@ class RecipeResolver { } } ``` -This works well when there are 2 - 3 args. But when you have many more, the resolver's method definitions becomes bloated. In that case you can use a class definition to describe the arguments. It looks like the object type class but it has `@ArgsType()` decorator on top. + +This works well when there are 2 - 3 args. But when you have many more, the resolver's method definitions becomes bloated. In that case you can use a class definition to describe the arguments. It looks like the object type class but it has `@ArgsType()` decorator on top. + ```typescript @ArgsType() class GetRecipesArgs { @@ -97,7 +104,8 @@ class GetRecipesArgs { skip: number; @Field(type => Int) - @Min(1) @Max(50) + @Min(1) + @Max(50) take = 25; @Field({ nullable: true }) @@ -111,6 +119,7 @@ class GetRecipesArgs { Then all that left to do is to use the args class as the type of the method parameter. We can use the destructuring syntax to have access to single arguments as variables, instead of the reference to the whole args object. + ```typescript @Resolver() class RecipeResolver { @@ -120,7 +129,7 @@ class RecipeResolver { // sample implementation let recipes = this.recipesCollection; if (title) { - recipes = recipes.filter(recipe => recipe.title === title) + recipes = recipes.filter(recipe => recipe.title === title); } return recipes.slice(startIndex, endIndex); } @@ -128,6 +137,7 @@ class RecipeResolver { ``` This declarations will result in the following part of the schema in SDL: + ```graphql type Query { recipes(skip: Int = 0, take: Int = 25, title: String): [Recipe!] @@ -135,23 +145,23 @@ type Query { ``` ### Input types + GraphQL's mutations we can create analogously, by declaring the class method, using `@Mutation` decorator, providing return type (if needed), creating arguments, etc. But for mutation we usually use `input` types, hence TypeGraphQL allows you to create inputs in the same way as the [object types](types-and-fields.md) but using `@InputType()` decorator: + ```typescript @InputType() -class AddRecipeInput { - -} +class AddRecipeInput {} ``` We can also leverage TypeScript type checking system and ensure that we won't accidentally change the type of property by implementing `Partial` type: + ```typescript @InputType() -class AddRecipeInput implements Partial { - -} +class AddRecipeInput implements Partial {} ``` Then we can declare all the input fields we would need, using `@Field()` decorator: + ```typescript @InputType({ description: "New recipe data" }) class AddRecipeInput implements Partial { @@ -166,15 +176,13 @@ class AddRecipeInput implements Partial { After that we can use the `AddRecipeInput` type in our mutation. We can do this inline (using `@Arg()` decorator) or as a field of the args class like in query's example above. We might also need access to the context. To achieve this we use the `@Ctx()` decorator with the optional user-defined `Context` interface: + ```typescript @Resolver() class RecipeResolver { // ... @Mutation() - addRecipe( - @Arg("data") newRecipeData: AddRecipeInput, - @Ctx() ctx: Context, - ): Recipe { + addRecipe(@Arg("data") newRecipeData: AddRecipeInput, @Ctx() ctx: Context): Recipe { // sample implementation const recipe = RecipesUtils.create(newRecipeData, ctx.user); this.recipesCollection.push(recipe); @@ -182,15 +190,18 @@ class RecipeResolver { } } ``` + Because our method is synchronous and explicitly returns `Recipe`, we can omit the `@Mutation()` type annotation. This declaration will result in the following part of the schema in SDL: + ```graphql input AddRecipeInput { title: String! description: String } ``` + ```graphql type Mutation { addRecipe(data: AddRecipeInput!): Recipe! @@ -200,9 +211,11 @@ type Mutation { By using parameter decorators, we can get rid of the unnecessary parameters (like `root`) that bloat our method definition and have to be ignored by prefixing the parameter name with `_`. Also, we can achieve a clean separation between GraphQL and our business code with decorators, so our resolvers and their methods behave just like services which we can easily unit-test. ## Field resolvers + Queries and mutations are not the only type of resolvers. We often create object type field resolvers (e.g. when a `user` type has a field `posts`) which we have to resolve by fetching relational data from the database. Field resolvers in TypeGraphQL are very similar to queries and mutations - we create them as a method on the resolver class but with a few modifications. Firstly, we need to declare which object type's fields we are resolving by providing the type to the `@Resolver` decorator: + ```typescript @Resolver(of => Recipe) class RecipeResolver { @@ -212,6 +225,7 @@ class RecipeResolver { Then we can create the class method that become the field resolver. In our example we have the `averageRating` field in the `Recipe` object type that should calculate the average from the `ratings` array. + ```typescript @Resolver(of => Recipe) class RecipeResolver { @@ -224,6 +238,7 @@ class RecipeResolver { ``` We need to mark the method as a field resolver with the `@FieldResolver()` decorator. Because we've defined the type of the field in the `Recipe` class definition, there's no need to do this again. We also need to decorate the method's parameters with `@Root` to inject the recipe object. + ```typescript @Resolver(of => Recipe) class RecipeResolver { @@ -239,6 +254,7 @@ class RecipeResolver { For enhanced type safety you can implement the `ResolverInterface` interface. It's a small helper that will check if the return type of field resolver methods, like `averageRating(...)`, match the `averageRating` property of the `Recipe` class and whether the first parameter of the method is the object type (`Recipe` class). + ```typescript @Resolver(of => Recipe) class RecipeResolver implements ResolverInterface { @@ -252,6 +268,7 @@ class RecipeResolver implements ResolverInterface { ``` Here is a full sample implementation of the `averageRating` field resolver: + ```typescript @Resolver(of => Recipe) class RecipeResolver implements ResolverInterface { @@ -260,9 +277,7 @@ class RecipeResolver implements ResolverInterface { @FieldResolver() averageRating(@Root() recipe: Recipe) { const ratingsSum = recipe.ratings.reduce((a, b) => a + b, 0); - return recipe.ratings.length - ? ratingsSum / recipe.ratings.length - : null; + return recipe.ratings.length ? ratingsSum / recipe.ratings.length : null; } } ``` @@ -276,7 +291,7 @@ class Recipe { title: string; @Field({ deprecationReason: "Use `title` instead" }) - get name(): string { + get name(): string { return this.title; } @@ -290,11 +305,11 @@ class Recipe { const ratingsSum = ratings.reduce((a, b) => a + b, 0); return ratingsSum / ratings.length; - }; + } } ``` -However, if the code is more complicated and has side effects (i.e. api calls, fetching from databases), use a resolver class's method instead. That way you can leverage the dependency injection mechanism, which is really helpful in testing. For example: +However, if the code is more complicated and has side effects (i.e. api calls, fetching from databases), use a resolver class's method instead. That way you can leverage the dependency injection mechanism, which is really helpful in testing. For example: ```typescript @Resolver(of => Recipe) @@ -315,8 +330,10 @@ class RecipeResolver implements ResolverInterface { Note that if a field name of a field resolver doesn't exit in resolver object type, it will create in schema a field with this name. This feature is useful when the field is purely calculable (eg. `averageRating` from `ratings` array) and you don't want to pollute the class signature. ## Resolvers inheritance + Inheritance of resolver classes is an advanced topic covered in [inheritance docs](inheritance.md#resolvers-inheritance). ## Examples + These code samples are made up just for tutorial purposes. -You can find more advanced, real examples in the repository [examples folder](https://github.com/MichalLytek/type-graphql/tree/master/examples). +You can find more advanced, real examples in the repository [examples folder](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples). diff --git a/website/versioned_docs/version-0.16.0/scalars.md b/website/versioned_docs/version-0.16.0/scalars.md index 777de840a..a7e0b50b6 100644 --- a/website/versioned_docs/version-0.16.0/scalars.md +++ b/website/versioned_docs/version-0.16.0/scalars.md @@ -5,12 +5,15 @@ original_id: scalars --- ## Aliases + TypeGraphQL provides aliases for 3 basic scalars: + - Int --> GraphQLInt; - Float --> GraphQLFloat; - ID --> GraphQLID; This shorthand allows you to save keystrokes when declaring field type: + ```typescript // import the aliases import { ID, Float, Int } from "type-graphql"; @@ -27,9 +30,11 @@ class MysteryObject { probability: number; } ``` + In the last case you can omit the `type => Float` since JavaScript `Number` will become `GraphQLFloat` in the schema automatically. -Other scalars - i.e. `GraphQLString` and `GraphQLBoolean` - do not need aliases. When possible, they will be reflected automatically: +Other scalars - i.e. `GraphQLString` and `GraphQLBoolean` - do not need aliases. When possible, they will be reflected automatically: + ```typescript @ObjectType() class User { @@ -42,11 +47,13 @@ class User { ``` However in some cases you will have to explicitly declare the string/bool scalar type. Use JS constructor functions (`String`, `Boolean`) then: + ```typescript @ObjectType() class SampleObject { @Field(type => String, { nullable: true }) - get optionalInfo(): string | undefined { // TS reflected type is `Object` :( + get optionalInfo(): string | undefined { + // TS reflected type is `Object` :( if (Math.random() > 0.5) { return "Gotcha!"; } @@ -55,13 +62,16 @@ class SampleObject { ``` ## Date Scalars + TypeGraphQL provides built-in scalars for the `Date` type. There are two versions of this scalar: + - timestamp based (`"timestamp"`) - `1518037458374` - ISO format (`"isoDate"`) - `"2018-02-07T21:04:39.573Z"` -They are exported from `type-graphql` package as `GraphQLISODateScalar` and `GraphQLTimestampScalar`. +They are exported from `type-graphql` package as `GraphQLISODateScalar` and `GraphQLTimestampScalar`. By default TypeGraphQL use the ISO date format, however you can change it in `buildSchema` options: + ```typescript import { buildSchema } from "type-graphql"; @@ -72,6 +82,7 @@ const schema = await buildSchema({ ``` There's no need to explicitly declare the field type then: + ```typescript @ObjectType() class User { @@ -79,12 +90,15 @@ class User { registrationDate: Date; } ``` + If you use `ts-node`, be aware you must execute it with the `--type-check` flag due to a [Date reflection bug](https://github.com/TypeStrong/ts-node/issues/511). ## Custom Scalars + TypeGraphQL also support custom scalar types. First of all, you need to create your own `GraphQLScalarType` instance or import the scalar type from a 3rd-party npm library. For example, Mongo's ObjectId: + ```typescript import { GraphQLScalarType, Kind } from "graphql"; import { ObjectId } from "mongodb"; @@ -108,6 +122,7 @@ export const ObjectIdScalar = new GraphQLScalarType({ ``` Then you can just use it in your field decorators: + ```typescript // import the earlier created const import { ObjectIdScalar } from "../my-scalars/ObjectId"; @@ -126,6 +141,7 @@ class User { ``` Optionally, you can declare the association between the reflected property type and your scalars to automatically map them (no need to explicit type annotation!): + ```typescript @ObjectType() class User { @@ -135,6 +151,7 @@ class User { ``` All you need to do is register the association map in the `buildSchema` options: + ```typescript import { ObjectId } from "mongodb"; import { ObjectIdScalar } from "../my-scalars/ObjectId"; @@ -145,4 +162,5 @@ const schema = await buildSchema({ scalarsMap: [{ type: ObjectId, scalar: ObjectIdScalar }], }); ``` + However, be aware that this will work only when the TypeScript reflection mechanism can handle it. So your class property type must be the `class`, not an enum, union or an interface. diff --git a/website/versioned_docs/version-0.16.0/subscriptions.md b/website/versioned_docs/version-0.16.0/subscriptions.md index 174a5b5b7..b5ed7cd81 100644 --- a/website/versioned_docs/version-0.16.0/subscriptions.md +++ b/website/versioned_docs/version-0.16.0/subscriptions.md @@ -9,9 +9,11 @@ However, oftentimes clients want to get pushed updates from the server when data To support that, GraphQL has a third operation: subscription. TypeGraphQL of course has great support for subscription, using [graphql-subscriptions](https://github.com/apollographql/graphql-subscriptions) package created by [Apollo GraphQL](https://www.apollographql.com/). ## Creating subscriptions + Subscription resolvers are basically similar to [queries and mutation resolvers](resolvers.md) but a little bit more complicated. At first, we create normal class method as always, this time annotated with `@Subscription()` decorator. + ```typescript class SampleResolver { // ... @@ -23,10 +25,11 @@ class SampleResolver { ``` Then we have to provide to which topics we want to subscribe. This can be a single topic string, an array of topics or a function to dynamically create a topic based on subscription args passed on the query. We can also use TS enums for enhanced type safety. + ```typescript class SampleResolver { // ... - @Subscription({ + @Subscription({ topics: "NOTIFICATIONS", // single topic topics: ["NOTIFICATIONS", "ERRORS"] // or topics array topics: ({ args, payload, context }) => args.topic // or dynamic topic function @@ -37,13 +40,13 @@ class SampleResolver { } ``` - We can also provide the `filter` option to decide which events from topics should trigger our subscription. This function should return `boolean` or `Promise`. + ```typescript class SampleResolver { // ... - @Subscription({ + @Subscription({ topics: "NOTIFICATIONS", filter: ({ payload, args }) => args.priorities.includes(payload.priority), }) @@ -54,10 +57,11 @@ class SampleResolver { ``` Then we can implement the subscription resolver. It will receive the payload from triggered topic of pubsub system using `@Root()` decorator. There we can transform it to the returned shape. + ```typescript class SampleResolver { // ... - @Subscription({ + @Subscription({ topics: "NOTIFICATIONS", filter: ({ payload, args }) => args.priorities.includes(payload.priority), }) @@ -68,18 +72,20 @@ class SampleResolver { return { ...notificationPayload, date: new Date(), - } + }; } } ``` ## Triggering subscriptions topics + Ok, we've created subscriptions, but what is the `pubsub` system and how to trigger the topics? They might be triggered from external sources like a DB. We also can do this in mutations, e.g. when we modify some resource that clients want to receive notifications about the changes. So, assuming we have this mutation for adding new comment: + ```typescript class SampleResolver { // ... @@ -94,14 +100,12 @@ class SampleResolver { We use `@PubSub()` decorator to inject the `pubsub` into our method params. There we can trigger the topics and send the payload to all topic subscribers. + ```typescript class SampleResolver { // ... @Mutation(returns => Boolean) - async addNewComment( - @Arg("comment") input: CommentInput, - @PubSub() pubSub: PubSubEngine, - ) { + async addNewComment(@Arg("comment") input: CommentInput, @PubSub() pubSub: PubSubEngine) { const comment = this.commentsService.createNew(input); await this.commentsRepository.save(comment); // here we can trigger subscriptions topics @@ -114,6 +118,7 @@ class SampleResolver { For easier testability (easier mocking/stubbing), we can also inject only the `publish` method bound to selected topic. To do this, we use `@PubSub("TOPIC_NAME")` decorator and the `Publisher` type: + ```typescript class SampleResolver { // ... @@ -134,23 +139,26 @@ class SampleResolver { And that's it! Now all subscriptions attached to `NOTIFICATIONS` topic will be triggered while performing `addNewComment` mutation. ## Using custom PubSub system + By default, TypeGraphQL use simple `PubSub` system from `grapqhl-subscriptions` which is based on EventEmitter. This solution has a big drawback that it will works correctly only when we have single instance (process) of our Node.js app. -For better scalability you'll want to use one of the [PubSub implementations]((https://github.com/apollographql/graphql-subscriptions#pubsub-implementations)) backed by an external store. +For better scalability you'll want to use one of the [PubSub implementations](<(https://github.com/apollographql/graphql-subscriptions#pubsub-implementations)>) backed by an external store. It might be e.g. Redis with [`graphql-redis-subscriptions`](https://github.com/davidyaha/graphql-redis-subscriptions) package. All you need to do is to create an instance of PubSub according to package instruction and the provide it to TypeGraphQL `buildSchema` options: + ```typescript const myRedisPubSub = getConfiguredRedisPubSub(); const schema = await buildSchema({ resolvers: [__dirname + "/**/*.resolver.ts"], pubSub: myRedisPubSub, -}) +}); ``` ## Creating subscription server + The [bootstrap guide](bootstrap.md) and all the earlier examples used [`apollo-server`](https://github.com/apollographql/apollo-server) to create HTTP endpoint for our GraphQL API. Fortunately, to make subscriptions work, we don't need to manually provide transport layer that doesn't have constraints of HTTP and can do a push-based communication (WebSockets). @@ -166,10 +174,12 @@ const server = new ApolloServer({ }, }); ``` + And it's done!. We have a working GraphQL subscription server on `/subscriptions`, along with a normal HTTP GraphQL server. ## Examples -You can see how the subscriptions works in a [simple example](https://github.com/MichalLytek/type-graphql/tree/master/examples/simple-subscriptions). -For production usage, it's better to use something more scalable, e.g. a Redis-based pubsub system - [working example is also available](https://github.com/MichalLytek/type-graphql/tree/master/examples/redis-subscriptions). +You can see how the subscriptions works in a [simple example](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/simple-subscriptions). + +For production usage, it's better to use something more scalable, e.g. a Redis-based pubsub system - [working example is also available](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/redis-subscriptions). However, to launch this example you need to have a running instance of Redis and you might have to modify the example code to provide your connection params. diff --git a/website/versioned_docs/version-0.16.0/types-and-fields.md b/website/versioned_docs/version-0.16.0/types-and-fields.md index 6b2882447..35725bc64 100644 --- a/website/versioned_docs/version-0.16.0/types-and-fields.md +++ b/website/versioned_docs/version-0.16.0/types-and-fields.md @@ -7,6 +7,7 @@ original_id: types-and-fields The main idea of TypeGraphQL is to automatically create GraphQL schema definition from TypeScript's classes. To avoid the need of schema definition files and interfaces describing the schema, we use a bit of reflection magic and decorators. Let's start with defining the example TypeScript class. It will represent our `Recipe` model with fields storing recipe's data: + ```typescript class Recipe { id: string; @@ -17,6 +18,7 @@ class Recipe { ``` First what we have to do is to decorate the class with e.g. `@ObjectType` decorator. It marks the class as the `type` known from GraphQL SDL or `GraphQLObjectType` from `graphql-js`: + ```typescript @ObjectType() class Recipe { @@ -29,6 +31,7 @@ class Recipe { Then we need to declare which class properties should be mapped to GraphQL fields. To do this, we use `@Field` decorator, which is also used to collect the metadata from TypeScript reflection system: + ```typescript @ObjectType() class Recipe { @@ -47,18 +50,20 @@ class Recipe { ``` For simple types (like `string` or `boolean`) it's enough but unfortunately, due to TypeScript's reflection limitation, we need to provide info about generic types (like `Array` or `Promise`). So to declare `Rate[]` type, there are two options available: + - `@Field(type => [Rate])` (the recommended way - explicit `[ ]` syntax for Array) - `@Field(itemType => Rate)` (`array` is inferred from reflection - also ok but prone to error) Why function syntax, not simple `{ type: Rate }` config object? Because this way we solve problems with circular dependencies (e.g. Post <--> User), so it was adopted as a convention. You can use the shorthand syntax `@Field(() => Rate)` if you want to save some keystrokes but it might be less readable for others. -For nullable properties like `averageRating` (it might be not defined when recipe has no ratings yet), we mark the class property as optional with `?:` operator and also have to pass `{ nullable: true }` decorator parameter. Be aware that when you declare your type as a nullable union (e.g. `string | null`), you need to explicitly provide the type to the `@Field` decorator. +For nullable properties like `averageRating` (it might be not defined when recipe has no ratings yet), we mark the class property as optional with `?:` operator and also have to pass `{ nullable: true }` decorator parameter. Be aware that when you declare your type as a nullable union (e.g. `string | null`), you need to explicitly provide the type to the `@Field` decorator. In case of lists, you may also need to define the nullability in a more detailed fashion. The basic `{ nullable: true | false }` settings apply only to the a whole list (`[Item!]` or `[Item!]!`), so if you need a sparse array, you can control the list items nullability via `nullable: items` (for `[Item]!`) or `nullable: itemsAndList` (for `[Item]`) option. In the config object we can also provide `description` and `deprecationReason` for GraphQL schema purposes. So after this changes our example class would look like this: + ```typescript @ObjectType({ description: "The recipe model" }) class Recipe { @@ -77,6 +82,7 @@ class Recipe { ``` Which in result will generate following part of GraphQL schema in SDL: + ```graphql type Recipe { id: ID! @@ -87,6 +93,7 @@ type Recipe { ``` Analogously, the `Rate` type class would look like this: + ```typescript @ObjectType() class Rate { @@ -99,7 +106,9 @@ class Rate { user: User; } ``` + which results in this equivalent of GraphQL's SDL: + ```graphql type Rate { value: Int! @@ -107,7 +116,7 @@ type Rate { } ``` -As you could see, for `id` property of `Recipe` we've passed `type => ID` and for `value` field of `Rate` - `type => Int`. This way we can overwrite the inferred type from reflection metadata. You can read more about the ID and Int scalars in [the scalars docs](scalars.md). There is also a section about the built-in `Date` scalar. +As you could see, for `id` property of `Recipe` we've passed `type => ID` and for `value` field of `Rate` - `type => Int`. This way we can overwrite the inferred type from reflection metadata. You can read more about the ID and Int scalars in [the scalars docs](scalars.md). There is also a section about the built-in `Date` scalar. Also the `user` property doesn't have `@Field()` decorator - this way we can hide some properties of our data model. In this case we need to store in database `user` info inside `Rate` object to prevent multiple rates but we don't want to make it public, accessible to every API consumer. diff --git a/website/versioned_docs/version-0.16.0/unions.md b/website/versioned_docs/version-0.16.0/unions.md index b995a5c97..80e18e138 100644 --- a/website/versioned_docs/version-0.16.0/unions.md +++ b/website/versioned_docs/version-0.16.0/unions.md @@ -4,11 +4,12 @@ id: version-0.16.0-unions original_id: unions --- -Sometimes our API has to be flexible and return not a specific type but the one from the range of possible types. The example might be a movie site's search functionality: using the provided phrase we search in database not only for movies but also for actors, so the query has to return the list `Movie` or `Actor` types. +Sometimes our API has to be flexible and return not a specific type but the one from the range of possible types. The example might be a movie site's search functionality: using the provided phrase we search in database not only for movies but also for actors, so the query has to return the list `Movie` or `Actor` types. You can read more about GraphQL union type in [official docs](http://graphql.org/learn/schema/#union-types). ## Usage + Let's start by creating the object types from example above: ```typescript @@ -21,6 +22,7 @@ class Movie { rating: number; } ``` + ```typescript @ObjectType() class Actor { @@ -33,11 +35,12 @@ class Actor { ``` Then we have to create the union type from the object types above: + ```typescript import { createUnionType } from "type-graphql"; const SearchResultUnion = createUnionType({ - name: "SearchResult", // the name of the GraphQL union + name: "SearchResult", // the name of the GraphQL union types: [Movie, Actor], // array of object types classes }); ``` @@ -45,13 +48,12 @@ const SearchResultUnion = createUnionType({ All that left to do is to use the union type in the query. Notice, that due to TypeScript's reflection limitation, you have to explicitly use `SearchResultUnion` value in `@Query` decorator return type annotation. For TS compile-time type safety you can also use `typeof SearchResultUnion` which is equal to type `Movie | Actor`. + ```typescript @Resolver() class SearchResolver { @Query(returns => [SearchResultUnion]) - async search( - @Arg("phrase") phrase: string, - ): Promise> { + async search(@Arg("phrase") phrase: string): Promise> { const movies = await Movies.findAll(phrase); const actors = await Actors.findAll(phrase); @@ -59,17 +61,21 @@ class SearchResolver { } } ``` + Be aware that when your query/mutation return type (or field type) is an union, you have to return an specific instance of the object type class. Otherwise, `graphql-js` will not be able to detect the underlying GraphQL type correctly when you use plain JS objects. **Et VoilΓ !** You can now build the schema and make the example query πŸ˜‰ + ```graphql query { search(phrase: "Holmes") { - ... on Actor { # maybe Katie Holmes? + ... on Actor { + # maybe Katie Holmes? name age } - ... on Movie { # for sure Sherlock Holmes! + ... on Movie { + # for sure Sherlock Holmes! name rating } diff --git a/website/versioned_docs/version-0.16.0/validation.md b/website/versioned_docs/version-0.16.0/validation.md index e397e3fd6..2b0e732a3 100644 --- a/website/versioned_docs/version-0.16.0/validation.md +++ b/website/versioned_docs/version-0.16.0/validation.md @@ -6,12 +6,15 @@ original_id: validation --- ## Scalars + The standard way to make sure that the input and arguments are correct, like the `email` field really has an e-mail, is to use [custom scalars](https://github.com/MichalLytek/type-graphql/blob/master/docs/scalars.md) e.g. `GraphQLEmail` from [`graphql-custom-types`](https://github.com/stylesuxx/graphql-custom-types). However creating scalars for all single case of data type (credit card number, base64, IP, URL) might be cumbersome. And that's why TypeGraphQL has built-in support for validation of arguments and inputs using [`class-validator`](https://github.com/typestack/class-validator) features! You can use awesomeness of decorators to declare the requirement for incoming data (e.g. number is in range 0-255 or password is longer than 8 chars) in an easy way. ## How to use + At first, you have to decorate the input/arguments class with appropriate decorators from `class-validator`. So we take this: + ```typescript @InputType() export class RecipeInput { @@ -22,7 +25,9 @@ export class RecipeInput { description?: string; } ``` + and produce this: + ```typescript import { MaxLength, Length } from "class-validator"; @@ -37,9 +42,11 @@ export class RecipeInput { description?: string; } ``` + And that's it! πŸ˜‰ TypeGraphQL will automatically validate your inputs and arguments based on the definitions: + ```typescript @Resolver(of => Recipe) export class RecipeResolver { @@ -56,6 +63,7 @@ export class RecipeResolver { Of course [there are many more decorators](https://github.com/typestack/class-validator#validation-decorators), not only the simple `@Length` used in the example above, so take a look at `class-validator` documentation. This feature is enabled by default. However, if you need, you can disable it: + ```typescript const schema = await buildSchema({ resolvers: [RecipeResolver], @@ -64,6 +72,7 @@ const schema = await buildSchema({ ``` And if you need, you can still enable it per resolver's argument: + ```typescript class RecipeResolver { @Mutation(returns => Recipe) @@ -74,6 +83,7 @@ class RecipeResolver { ``` You can also pass `ValidatorOptions` object, for setting features like [validation groups](https://github.com/typestack/class-validator#validation-groups): + ```typescript class RecipeResolver { @Mutation(returns => Recipe) @@ -91,19 +101,25 @@ Note that by default `skipMissingProperties` setting of `class-validator` is set GraphQL will also checks whether the fields have correct types (String, Int, Float, Boolean, etc.) so you don't have to use `@IsOptional`, `@Allow`, `@IsString` or `@IsInt` decorators at all! ## Response to the client + When client send incorrect data to the server: + ```graphql mutation ValidationMutation { - addRecipe(input: { - # too long! - title: "Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet" - }) { + addRecipe( + input: { + # too long! + title: "Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet" + } + ) { title creationDate } } ``` + the [`ArgumentValidationError`](https://github.com/MichalLytek/type-graphql/blob/master/src/errors/ArgumentValidationError.ts) will be throwed. To send more detailed error info to the client than `Argument Validation Error` string, you have to format the error - `TypeGraphQL` provides a helper for this case. Example using the `apollo-server` package from [bootstrap guide](bootstrap.md): + ```typescript import { formatArgumentValidationError } from "type-graphql"; @@ -116,6 +132,7 @@ const server = new ApolloServer({ ``` So when `ArgumentValidationError` occurs, client will receive this JSON with nice `validationErrors` property: + ```json { "errors": [ @@ -127,9 +144,7 @@ So when `ArgumentValidationError` occurs, client will receive this JSON with nic "column": 3 } ], - "path": [ - "addRecipe" - ], + "path": ["addRecipe"], "validationErrors": [ { "target": { @@ -152,4 +167,5 @@ So when `ArgumentValidationError` occurs, client will receive this JSON with nic Of course you can replace this with your own custom implementation of function that will transform `GraphQLError` with `ValidationError` array to the desired output format. ## Example -You can see how this fits together in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/master/examples/automatic-validation). + +You can see how this fits together in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v0.16.0/examples/automatic-validation). diff --git a/website/versioned_docs/version-0.17.0/authorization.md b/website/versioned_docs/version-0.17.0/authorization.md index a096d49dd..71b19684b 100644 --- a/website/versioned_docs/version-0.17.0/authorization.md +++ b/website/versioned_docs/version-0.17.0/authorization.md @@ -162,4 +162,4 @@ Then you can use standard, token based authorization in HTTP header like in clas ## Example -You can see how this works together in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/master/examples/authorization). +You can see how this works together in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/authorization). diff --git a/website/versioned_docs/version-0.17.0/complexity.md b/website/versioned_docs/version-0.17.0/complexity.md index 4c8b37f78..e04d6dc72 100644 --- a/website/versioned_docs/version-0.17.0/complexity.md +++ b/website/versioned_docs/version-0.17.0/complexity.md @@ -81,4 +81,4 @@ For more info about how query complexity is computed, please visit [graphql-quer ## Example -You can see how this works together in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/master/examples/query-complexity). +You can see how this works together in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/query-complexity). diff --git a/website/versioned_docs/version-0.17.0/dependency-injection.md b/website/versioned_docs/version-0.17.0/dependency-injection.md index 2d82ac74e..20344f4f8 100644 --- a/website/versioned_docs/version-0.17.0/dependency-injection.md +++ b/website/versioned_docs/version-0.17.0/dependency-injection.md @@ -70,7 +70,7 @@ export class RecipeService { ### Example -You can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/master/examples/using-container). +You can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/using-container). ## Scoped containers @@ -145,4 +145,4 @@ The only thing that left is the container configuration - you need to check out ### Example -For more advanced usage example with scoped containers, check out [advanced example with scoped containers](https://github.com/MichalLytek/type-graphql/tree/master/examples/using-scoped-container). +For more advanced usage example with scoped containers, check out [advanced example with scoped containers](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/using-scoped-container). diff --git a/website/versioned_docs/version-0.17.0/generic-types.md b/website/versioned_docs/version-0.17.0/generic-types.md index d8b21341d..a61654cba 100644 --- a/website/versioned_docs/version-0.17.0/generic-types.md +++ b/website/versioned_docs/version-0.17.0/generic-types.md @@ -129,4 +129,4 @@ class UserResolver { ## Examples -More advanced usage example of a generic types feature you can see in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/master/examples/generic-types). +More advanced usage example of a generic types feature you can see in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/generic-types). diff --git a/website/versioned_docs/version-0.17.0/getting-started.md b/website/versioned_docs/version-0.17.0/getting-started.md index bb381b273..8081f5ce7 100644 --- a/website/versioned_docs/version-0.17.0/getting-started.md +++ b/website/versioned_docs/version-0.17.0/getting-started.md @@ -110,7 +110,7 @@ The detailed rules when and why we declare `returns => Recipe` functions and oth ## Inputs and arguments -Ok, but what are `NewRecipeInput` and `RecipesArgs`? They are of course classes: +Ok, but what are `NewRecipeInput` and `RecipesArgs`? They are, of course, classes: ```typescript @InputType() diff --git a/website/versioned_docs/version-0.17.0/inheritance.md b/website/versioned_docs/version-0.17.0/inheritance.md index 3168f1310..50e2c9124 100644 --- a/website/versioned_docs/version-0.17.0/inheritance.md +++ b/website/versioned_docs/version-0.17.0/inheritance.md @@ -140,6 +140,6 @@ Be aware that if you want to overwrite the query/mutation/subscription from pare ## Examples -More advanced usage example of types inheritance (and interfaces) you can see in [the example folder](https://github.com/MichalLytek/type-graphql/tree/master/examples/interfaces-inheritance). +More advanced usage example of types inheritance (and interfaces) you can see in [the example folder](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/interfaces-inheritance). -For more advanced resolvers inheritance example, please go to [this example folder](https://github.com/MichalLytek/type-graphql/tree/master/examples/resolvers-inheritance). +For more advanced resolvers inheritance example, please go to [this example folder](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/resolvers-inheritance). diff --git a/website/versioned_docs/version-0.17.0/interfaces.md b/website/versioned_docs/version-0.17.0/interfaces.md index 54bcfb59f..9af49c410 100644 --- a/website/versioned_docs/version-0.17.0/interfaces.md +++ b/website/versioned_docs/version-0.17.0/interfaces.md @@ -49,4 +49,4 @@ Be aware that when your object type is implementing GraphQL interface type, **yo ## Examples -More advanced usage example of interfaces (and types inheritance), e.g. with query returning interface type, you can see in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/master/examples/interfaces-inheritance). +More advanced usage example of interfaces (and types inheritance), e.g. with query returning interface type, you can see in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/interfaces-inheritance). diff --git a/website/versioned_docs/version-0.17.0/resolvers.md b/website/versioned_docs/version-0.17.0/resolvers.md index f196d13ce..84c96d385 100644 --- a/website/versioned_docs/version-0.17.0/resolvers.md +++ b/website/versioned_docs/version-0.17.0/resolvers.md @@ -340,4 +340,4 @@ Inheritance of resolver classes is an advanced topic covered in [resolvers inher ## Examples These code samples are made up just for tutorial purposes. -You can find more advanced, real examples in the repository [examples folder](https://github.com/MichalLytek/type-graphql/tree/master/examples). +You can find more advanced, real examples in the repository [examples folder](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples). diff --git a/website/versioned_docs/version-0.17.0/subscriptions.md b/website/versioned_docs/version-0.17.0/subscriptions.md index 07b327e53..a85da481a 100644 --- a/website/versioned_docs/version-0.17.0/subscriptions.md +++ b/website/versioned_docs/version-0.17.0/subscriptions.md @@ -179,7 +179,7 @@ And it's done!. We have a working GraphQL subscription server on `/subscriptions ## Examples -You can see how the subscriptions works in a [simple example](https://github.com/MichalLytek/type-graphql/tree/master/examples/simple-subscriptions). +You can see how the subscriptions works in a [simple example](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/simple-subscriptions). -For production usage, it's better to use something more scalable, e.g. a Redis-based pubsub system - [working example is also available](https://github.com/MichalLytek/type-graphql/tree/master/examples/redis-subscriptions). +For production usage, it's better to use something more scalable, e.g. a Redis-based pubsub system - [working example is also available](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/redis-subscriptions). However, to launch this example you need to have a running instance of Redis and you might have to modify the example code to provide your connection params. diff --git a/website/versioned_docs/version-0.17.0/validation.md b/website/versioned_docs/version-0.17.0/validation.md index 87422a3d7..f4f46c508 100644 --- a/website/versioned_docs/version-0.17.0/validation.md +++ b/website/versioned_docs/version-0.17.0/validation.md @@ -169,4 +169,4 @@ Of course you can also create your own custom implementation of the `formatError ## Example -You can see how this fits together in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/master/examples/automatic-validation). +You can see how this fits together in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v0.17.0/examples/automatic-validation). diff --git a/website/versioned_docs/version-0.17.1/authorization.md b/website/versioned_docs/version-0.17.1/authorization.md index 510750c46..81f7e6552 100644 --- a/website/versioned_docs/version-0.17.1/authorization.md +++ b/website/versioned_docs/version-0.17.1/authorization.md @@ -163,4 +163,4 @@ Then we can use standard, token based authorization in the HTTP header like in c ## Example -See how this works in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/master/examples/authorization). +See how this works in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/authorization). diff --git a/website/versioned_docs/version-0.17.1/complexity.md b/website/versioned_docs/version-0.17.1/complexity.md index 8bf1055b7..172076b2c 100644 --- a/website/versioned_docs/version-0.17.1/complexity.md +++ b/website/versioned_docs/version-0.17.1/complexity.md @@ -81,4 +81,4 @@ For more info about how query complexity is computed, please visit [graphql-quer ## Example -See how this works in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/master/examples/query-complexity). +See how this works in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/query-complexity). diff --git a/website/versioned_docs/version-0.17.1/dependency-injection.md b/website/versioned_docs/version-0.17.1/dependency-injection.md index 58d544b7f..b17d40a84 100644 --- a/website/versioned_docs/version-0.17.1/dependency-injection.md +++ b/website/versioned_docs/version-0.17.1/dependency-injection.md @@ -70,7 +70,7 @@ export class RecipeService { ### Example -You can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/master/examples/using-container). +You can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/using-container). ## Scoped containers @@ -145,4 +145,4 @@ The only thing that's left is the container configuration - we need to check out ### Example -For a more advanced usage example with scoped containers, check out [advanced example with scoped containers](https://github.com/MichalLytek/type-graphql/tree/master/examples/using-scoped-container). +For a more advanced usage example with scoped containers, check out [advanced example with scoped containers](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/using-scoped-container). diff --git a/website/versioned_docs/version-0.17.1/generic-types.md b/website/versioned_docs/version-0.17.1/generic-types.md index 2715a867a..9d3d56a2d 100644 --- a/website/versioned_docs/version-0.17.1/generic-types.md +++ b/website/versioned_docs/version-0.17.1/generic-types.md @@ -133,4 +133,4 @@ class UserResolver { ## Examples -A more advanced usage example of the generic types feature can be found in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/master/examples/generic-types). +A more advanced usage example of the generic types feature can be found in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/generic-types). diff --git a/website/versioned_docs/version-0.17.1/getting-started.md b/website/versioned_docs/version-0.17.1/getting-started.md index b57fd04ec..d40a3cdf6 100644 --- a/website/versioned_docs/version-0.17.1/getting-started.md +++ b/website/versioned_docs/version-0.17.1/getting-started.md @@ -110,7 +110,7 @@ The detailed rules for when and why we declare `returns => Recipe` functions and ## Inputs and Arguments -Ok, but what are `NewRecipeInput` and `RecipesArgs`? They are of course classes: +Ok, but what are `NewRecipeInput` and `RecipesArgs`? They are, of course, classes: ```typescript @InputType() diff --git a/website/versioned_docs/version-0.17.1/inheritance.md b/website/versioned_docs/version-0.17.1/inheritance.md index 057d0078d..5ed951a32 100644 --- a/website/versioned_docs/version-0.17.1/inheritance.md +++ b/website/versioned_docs/version-0.17.1/inheritance.md @@ -140,6 +140,6 @@ We must be aware that if we want to overwrite the query/mutation/subscription fr ## Examples -More advanced usage examples of type inheritance (and interfaces) can be found in [the example folder](https://github.com/MichalLytek/type-graphql/tree/master/examples/interfaces-inheritance). +More advanced usage examples of type inheritance (and interfaces) can be found in [the example folder](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/interfaces-inheritance). -For a more advanced resolver inheritance example, please go to [this example folder](https://github.com/MichalLytek/type-graphql/tree/master/examples/resolvers-inheritance). +For a more advanced resolver inheritance example, please go to [this example folder](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/resolvers-inheritance). diff --git a/website/versioned_docs/version-0.17.1/interfaces.md b/website/versioned_docs/version-0.17.1/interfaces.md index 7308a19b2..c1f33f52d 100644 --- a/website/versioned_docs/version-0.17.1/interfaces.md +++ b/website/versioned_docs/version-0.17.1/interfaces.md @@ -49,4 +49,4 @@ Be aware that when our object type is implementing a GraphQL interface type, **w ## Examples -For more advanced usage examples of interfaces (and type inheritance), e.g. with query returning an interface type, got to [this examples folder](https://github.com/MichalLytek/type-graphql/tree/master/examples/interfaces-inheritance). +For more advanced usage examples of interfaces (and type inheritance), e.g. with query returning an interface type, got to [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/interfaces-inheritance). diff --git a/website/versioned_docs/version-0.17.1/resolvers.md b/website/versioned_docs/version-0.17.1/resolvers.md index 4c32a413b..aae66c74a 100644 --- a/website/versioned_docs/version-0.17.1/resolvers.md +++ b/website/versioned_docs/version-0.17.1/resolvers.md @@ -339,4 +339,4 @@ Resolver class `inheritance` is an advanced topic covered in the [resolver inher ## Examples These code samples are just made up for tutorial purposes. -You can find more advanced, real examples in the [examples folder on the repository](https://github.com/MichalLytek/type-graphql/tree/master/examples). +You can find more advanced, real examples in the [examples folder on the repository](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples). diff --git a/website/versioned_docs/version-0.17.1/subscriptions.md b/website/versioned_docs/version-0.17.1/subscriptions.md index 0d31b99da..7e0d14204 100644 --- a/website/versioned_docs/version-0.17.1/subscriptions.md +++ b/website/versioned_docs/version-0.17.1/subscriptions.md @@ -178,7 +178,7 @@ And it's done! We have a working GraphQL subscription server on `/subscriptions` ## Examples -See how subscriptions work in a [simple example](https://github.com/MichalLytek/type-graphql/tree/master/examples/simple-subscriptions). +See how subscriptions work in a [simple example](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/simple-subscriptions). -For production usage, it's better to use something more scalable like a Redis-based pubsub system - [a working example is also available](https://github.com/MichalLytek/type-graphql/tree/master/examples/redis-subscriptions). +For production usage, it's better to use something more scalable like a Redis-based pubsub system - [a working example is also available](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/redis-subscriptions). However, to launch this example you need to have a running instance of Redis and you might have to modify the example code to provide your connection parameters. diff --git a/website/versioned_docs/version-0.17.1/validation.md b/website/versioned_docs/version-0.17.1/validation.md index 37eb8821d..8a7dc763f 100644 --- a/website/versioned_docs/version-0.17.1/validation.md +++ b/website/versioned_docs/version-0.17.1/validation.md @@ -169,4 +169,4 @@ Of course we can also create our own custom implementation of the `formatError` ## Example -To see how this works, check out the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/master/examples/automatic-validation). +To see how this works, check out the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v0.17.1/examples/automatic-validation). diff --git a/website/versioned_docs/version-0.17.2/getting-started.md b/website/versioned_docs/version-0.17.2/getting-started.md index fe519957f..fc221d773 100644 --- a/website/versioned_docs/version-0.17.2/getting-started.md +++ b/website/versioned_docs/version-0.17.2/getting-started.md @@ -110,7 +110,7 @@ The detailed rules for when and why we declare `returns => Recipe` functions and ## Inputs and Arguments -Ok, but what are `NewRecipeInput` and `RecipesArgs`? They are of course classes: +Ok, but what are `NewRecipeInput` and `RecipesArgs`? They are, of course, classes: ```typescript @InputType() diff --git a/website/versioned_docs/version-0.17.5/dependency-injection.md b/website/versioned_docs/version-0.17.5/dependency-injection.md index 422974da6..7a7ce878a 100644 --- a/website/versioned_docs/version-0.17.5/dependency-injection.md +++ b/website/versioned_docs/version-0.17.5/dependency-injection.md @@ -70,7 +70,7 @@ export class RecipeService { ### Example -You can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/master/examples/using-container). +You can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/v0.17.5/examples/using-container). ## Scoped containers @@ -120,7 +120,7 @@ const server = new ApolloServer({ We also have to dispose the container after the request has been handled and the response is ready. Otherwise, there would be a huge memory leak as the new instances of services and resolvers have been created for each request but they haven't been cleaned up. -Apollo Server since version 2.2.0 has a [plugins](https://www.apollographql.com/docs/apollo-server/integrations/plugins/) feature that supports [`willSendResponse`](https://www.apollographql.com/docs/apollo-server/integrations/plugins/#willsendresponse) lifecycle event. We can leverage it to clean up the container after handling the request. +Apollo Server since version 2.2.0 has a [plugins](https://www.apollographql.com/docs/apollo-server/integrations/plugins/) feature that supports [`willSendResponse`](https://www.apollographql.com/docs/apollo-server/integrations/plugins/#willsendresponse) lifecycle event. We can leverage it to clean up the container after handling the request. Example using `TypeDI` and `apollo-server` with plugins approach: diff --git a/website/versioned_docs/version-1.0.0/getting-started.md b/website/versioned_docs/version-1.0.0/getting-started.md index 680a5d57f..0f6812c7a 100644 --- a/website/versioned_docs/version-1.0.0/getting-started.md +++ b/website/versioned_docs/version-1.0.0/getting-started.md @@ -110,7 +110,7 @@ The detailed rules for when and why we declare `returns => Recipe` functions and ## Inputs and Arguments -Ok, but what are `NewRecipeInput` and `RecipesArgs`? They are of course classes: +Ok, but what are `NewRecipeInput` and `RecipesArgs`? They are, of course, classes: ```typescript @InputType() diff --git a/website/versioned_docs/version-1.0.0/prisma.md b/website/versioned_docs/version-1.0.0/prisma.md index b0a9ed591..d9d675eef 100644 --- a/website/versioned_docs/version-1.0.0/prisma.md +++ b/website/versioned_docs/version-1.0.0/prisma.md @@ -1,37 +1,36 @@ --- -title: Prisma 2 Integration -sidebar_label: Prisma 2 +title: Prisma Integration +sidebar_label: Prisma id: version-1.0.0-prisma original_id: prisma --- -TypeGraphQL provides an integration with Prisma 2 by the [`typegraphql-prisma` package](https://www.npmjs.com/package/typegraphql-prisma). +TypeGraphQL provides an integration with Prisma by the [`typegraphql-prisma` package](https://www.npmjs.com/package/typegraphql-prisma). -It generates the type classes and CRUD resolvers based on the Prisma schema, so you can execute complex queries or mutations that corresponds to the Prisma actions, without having to write any code for that. +It generates the type classes and CRUD resolvers based on the Prisma schema, so we can execute complex queries or mutations that corresponds to the Prisma actions, without having to write any code for that. ## Overview -To make use of the prisma integration, first you need to add a new generator to the `schema.prisma` file: +To make use of the prisma integration, first we need to add a new generator to the `schema.prisma` file: ```sh generator typegraphql { - provider = "node node_modules/typegraphql-prisma/generator.js" - output = "../src/generated/typegraphql-prisma" + provider = "typegraphql-prisma" } ``` -Then, after running `prisma generate` you can import the generated classes and use them to build your schema: +Then, after running `prisma generate` we can import the generated resolvers classes and use them to build our schema: ```typescript -import { User, UserRelationsResolver, UserCrudResolver } from "./generated/typegraphql-prisma"; +import { resolvers } from "@generated/type-graphql"; const schema = await buildSchema({ - resolvers: [CustomUserResolver, UserRelationsResolver, UserCrudResolver], + resolvers, validate: false, }); ``` -So you will be able to execute such complex query that talks with the db in just a few minutes! +So we will be able to execute a complex query, that talks with the real database, in just a few minutes! ```graphql query GetSomeUsers { @@ -50,6 +49,6 @@ query GetSomeUsers { ## Documentation and examples -To read about all the `typegraphql-prisma` features, like exposing selected Prisma actions or changing exposed model type name, as well as how to write a custom query or how to add some fields to model type, please check the docs [on the separate GitHub repository](https://github.com/MichalLytek/typegraphql-prisma/blob/main/Readme.md). +To read about all the `typegraphql-prisma` features, like exposing selected Prisma actions or changing exposed model type name, as well as how to write a custom query or how to add some fields to model type, please check the docs [on the dedicated website](https://prisma.typegraphql.com/). -You can find there also some examples and more detailed info about the installation and the configuration. +There also can be found the links to some examples and more detailed info about the installation and the configuration. diff --git a/website/versioned_docs/version-1.1.0/prisma.md b/website/versioned_docs/version-1.1.0/prisma.md deleted file mode 100644 index 0f58a2a90..000000000 --- a/website/versioned_docs/version-1.1.0/prisma.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: Prisma 2 Integration -sidebar_label: Prisma 2 -id: version-1.1.0-prisma -original_id: prisma ---- - -TypeGraphQL provides an integration with Prisma 2 by the [`typegraphql-prisma` package](https://www.npmjs.com/package/typegraphql-prisma). - -It generates the type classes and CRUD resolvers based on the Prisma schema, so you can execute complex queries or mutations that corresponds to the Prisma actions, without having to write any code for that. - -## Overview - -To make use of the prisma integration, first you need to add a new generator to the `schema.prisma` file: - -```sh -generator typegraphql { - provider = "typegraphql-prisma" - output = "../src/generated/typegraphql-prisma" -} -``` - -Then, after running `prisma generate` you can import the generated classes and use them to build your schema: - -```typescript -import { User, UserRelationsResolver, UserCrudResolver } from "./generated/typegraphql-prisma"; - -const schema = await buildSchema({ - resolvers: [CustomUserResolver, UserRelationsResolver, UserCrudResolver], - validate: false, -}); -``` - -So you will be able to execute such complex query that talks with the db in just a few minutes! - -```graphql -query GetSomeUsers { - users(where: { email: { contains: "prisma" } }, orderBy: { name: desc }) { - id - name - email - posts(take: 10, orderBy: { updatedAt: desc }) { - published - title - content - } - } -} -``` - -## Documentation and examples - -To read about all the `typegraphql-prisma` features, like exposing selected Prisma actions or changing exposed model type name, as well as how to write a custom query or how to add some fields to model type, please check the docs [on the separate GitHub repository](https://github.com/MichalLytek/typegraphql-prisma/blob/main/Readme.md). - -You can find there also some examples and more detailed info about the installation and the configuration. diff --git a/website/versioned_docs/version-1.2.0-rc.1/authorization.md b/website/versioned_docs/version-1.2.0-rc.1/authorization.md index 3d843b9d7..09057aee5 100644 --- a/website/versioned_docs/version-1.2.0-rc.1/authorization.md +++ b/website/versioned_docs/version-1.2.0-rc.1/authorization.md @@ -181,4 +181,4 @@ Then we can use standard, token based authorization in the HTTP header like in c ## Example -See how this works in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/master/examples/authorization). +See how this works in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/authorization). diff --git a/website/versioned_docs/version-1.2.0-rc.1/complexity.md b/website/versioned_docs/version-1.2.0-rc.1/complexity.md index fba4a5a28..6e73d5e14 100644 --- a/website/versioned_docs/version-1.2.0-rc.1/complexity.md +++ b/website/versioned_docs/version-1.2.0-rc.1/complexity.md @@ -98,4 +98,4 @@ For more info about how query complexity is computed, please visit [graphql-quer ## Example -See how this works in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/master/examples/query-complexity). +See how this works in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/query-complexity). diff --git a/website/versioned_docs/version-1.2.0-rc.1/custom-decorators.md b/website/versioned_docs/version-1.2.0-rc.1/custom-decorators.md index 1dee0ebef..cb79035a6 100644 --- a/website/versioned_docs/version-1.2.0-rc.1/custom-decorators.md +++ b/website/versioned_docs/version-1.2.0-rc.1/custom-decorators.md @@ -103,4 +103,4 @@ export class RecipeResolver { ## Example -See how different kinds of custom decorators work in the [custom decorators and middlewares example](https://github.com/MichalLytek/type-graphql/tree/master/examples/middlewares-custom-decorators). +See how different kinds of custom decorators work in the [custom decorators and middlewares example](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/middlewares-custom-decorators). diff --git a/website/versioned_docs/version-1.2.0-rc.1/dependency-injection.md b/website/versioned_docs/version-1.2.0-rc.1/dependency-injection.md index 61ea5bc36..5a572ec10 100644 --- a/website/versioned_docs/version-1.2.0-rc.1/dependency-injection.md +++ b/website/versioned_docs/version-1.2.0-rc.1/dependency-injection.md @@ -155,6 +155,6 @@ The only thing that's left is the container configuration - we need to check out ## Example -You can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/master/examples/using-container). +You can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/using-container). -For a more advanced usage example with scoped containers, check out [advanced example with scoped containers](https://github.com/MichalLytek/type-graphql/tree/master/examples/using-scoped-container). +For a more advanced usage example with scoped containers, check out [advanced example with scoped containers](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/using-scoped-container). diff --git a/website/versioned_docs/version-1.2.0-rc.1/examples.md b/website/versioned_docs/version-1.2.0-rc.1/examples.md index e4cbc2395..a08e1d4de 100644 --- a/website/versioned_docs/version-1.2.0-rc.1/examples.md +++ b/website/versioned_docs/version-1.2.0-rc.1/examples.md @@ -11,39 +11,39 @@ All examples have an `examples.gql` file with sample queries/mutations/subscript ## Basics -- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/master/examples/simple-usage) +- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/simple-usage) ## Advanced -- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/master/examples/enums-and-unions) -- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/master/examples/simple-subscriptions) -- [Subscriptions (using Redis)](https://github.com/MichalLytek/type-graphql/tree/master/examples/redis-subscriptions) -- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/master/examples/interfaces-inheritance) -- [Extensions (metadata)](https://github.com/MichalLytek/type-graphql/tree/master/examples/extensions) +- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/enums-and-unions) +- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/simple-subscriptions) +- [Subscriptions (using Redis)](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/redis-subscriptions) +- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/interfaces-inheritance) +- [Extensions (metadata)](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/extensions) ## Features usage -- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/master/examples/using-container) - - [Scoped containers](https://github.com/MichalLytek/type-graphql/tree/master/examples/using-scoped-container) -- [Authorization](https://github.com/MichalLytek/type-graphql/tree/master/examples/authorization) -- [Validation](https://github.com/MichalLytek/type-graphql/tree/master/examples/automatic-validation) - - [Custom validation](https://github.com/MichalLytek/type-graphql/tree/master/examples/custom-validation) -- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/master/examples/interfaces-inheritance) -- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/master/examples/resolvers-inheritance) -- [Generic types](https://github.com/MichalLytek/type-graphql/tree/master/examples/generic-types) -- [Mixin classes](https://github.com/MichalLytek/type-graphql/tree/master/examples/mixin-classes) -- [Middlewares and Custom Decorators](https://github.com/MichalLytek/type-graphql/tree/master/examples/middlewares-custom-decorators) -- [Query complexity](https://github.com/MichalLytek/type-graphql/tree/master/examples/query-complexity) +- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/using-container) + - [Scoped containers](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/using-scoped-container) +- [Authorization](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/authorization) +- [Validation](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/automatic-validation) + - [Custom validation](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/custom-validation) +- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/interfaces-inheritance) +- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/resolvers-inheritance) +- [Generic types](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/generic-types) +- [Mixin classes](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/mixin-classes) +- [Middlewares and Custom Decorators](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/middlewares-custom-decorators) +- [Query complexity](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/query-complexity) ## 3rd party libs integration -- [TypeORM (manual, synchronous) \*](https://github.com/MichalLytek/type-graphql/tree/master/examples/typeorm-basic-usage) -- [TypeORM (automatic, lazy relations) \*](https://github.com/MichalLytek/type-graphql/tree/master/examples/typeorm-lazy-relations) -- [MikroORM](https://github.com/MichalLytek/type-graphql/tree/master/examples/mikro-orm) -- [Typegoose](https://github.com/MichalLytek/type-graphql/tree/master/examples/typegoose) -- [Apollo federation](https://github.com/MichalLytek/type-graphql/tree/master/examples/apollo-federation) -- [Apollo Cache Control](https://github.com/MichalLytek/type-graphql/tree/master/examples/apollo-cache) -- [Apollo Client state](https://github.com/MichalLytek/type-graphql/tree/master/examples/apollo-client) -- [GraphQL Modules](https://github.com/MichalLytek/type-graphql/tree/master/examples/graphql-modules) +- [TypeORM (manual, synchronous) \*](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/typeorm-basic-usage) +- [TypeORM (automatic, lazy relations) \*](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/typeorm-lazy-relations) +- [MikroORM](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/mikro-orm) +- [Typegoose](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/typegoose) +- [Apollo federation](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/apollo-federation) +- [Apollo Cache Control](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/apollo-cache) +- [Apollo Client state](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/apollo-client) +- [GraphQL Modules](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/graphql-modules) _\* Note that we need to edit the TypeORM example's `index.ts` with the credentials of our local database_ diff --git a/website/versioned_docs/version-1.2.0-rc.1/extensions.md b/website/versioned_docs/version-1.2.0-rc.1/extensions.md index e2b7def53..965366823 100644 --- a/website/versioned_docs/version-1.2.0-rc.1/extensions.md +++ b/website/versioned_docs/version-1.2.0-rc.1/extensions.md @@ -116,4 +116,4 @@ export class LoggerMiddleware implements MiddlewareInterface { ## Examples -You can see more detailed examples of usage [here](https://github.com/MichalLytek/type-graphql/tree/master/examples/extensions). +You can see more detailed examples of usage [here](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/extensions). diff --git a/website/versioned_docs/version-1.2.0-rc.1/generic-types.md b/website/versioned_docs/version-1.2.0-rc.1/generic-types.md index afa9e6b9f..55077e873 100644 --- a/website/versioned_docs/version-1.2.0-rc.1/generic-types.md +++ b/website/versioned_docs/version-1.2.0-rc.1/generic-types.md @@ -168,4 +168,4 @@ class UserResolver { ## Examples -A more advanced usage example of the generic types feature can be found in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/master/examples/generic-types). +A more advanced usage example of the generic types feature can be found in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/generic-types). diff --git a/website/versioned_docs/version-1.2.0-rc.1/interfaces.md b/website/versioned_docs/version-1.2.0-rc.1/interfaces.md index 79d9779dc..76c398b63 100644 --- a/website/versioned_docs/version-1.2.0-rc.1/interfaces.md +++ b/website/versioned_docs/version-1.2.0-rc.1/interfaces.md @@ -255,4 +255,4 @@ However in case of interfaces, it might be a little bit more tricky than with un ## Examples -For more advanced usage examples of interfaces (and type inheritance), e.g. with query returning an interface type, go to [this examples folder](https://github.com/MichalLytek/type-graphql/tree/master/examples/interfaces-inheritance). +For more advanced usage examples of interfaces (and type inheritance), e.g. with query returning an interface type, go to [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/interfaces-inheritance). diff --git a/website/versioned_docs/version-1.2.0-rc.1/middlewares.md b/website/versioned_docs/version-1.2.0-rc.1/middlewares.md index ea9c74498..5605b467a 100644 --- a/website/versioned_docs/version-1.2.0-rc.1/middlewares.md +++ b/website/versioned_docs/version-1.2.0-rc.1/middlewares.md @@ -186,4 +186,4 @@ If we want to use middlewares with a more descriptive and declarative API, we ca ## Example -See how different kinds of middlewares work in the [middlewares and custom decorators example](https://github.com/MichalLytek/type-graphql/tree/master/examples/middlewares-custom-decorators). +See how different kinds of middlewares work in the [middlewares and custom decorators example](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/middlewares-custom-decorators). diff --git a/website/versioned_docs/version-1.2.0-rc.1/performance.md b/website/versioned_docs/version-1.2.0-rc.1/performance.md index 2040f634c..1f276799b 100644 --- a/website/versioned_docs/version-1.2.0-rc.1/performance.md +++ b/website/versioned_docs/version-1.2.0-rc.1/performance.md @@ -10,7 +10,7 @@ While this enable easy and convenient development, it's sometimes a tradeoff in ## Benchmarks -To measure the overhead of the abstraction, a few demo examples were made to compare the usage of TypeGraphQL against the implementations using "bare metal" - raw `graphql-js` library. The benchmarks are located in a [folder on the GitHub repo](https://github.com/MichalLytek/type-graphql/tree/master/benchmarks). +To measure the overhead of the abstraction, a few demo examples were made to compare the usage of TypeGraphQL against the implementations using "bare metal" - raw `graphql-js` library. The benchmarks are located in a [folder on the GitHub repo](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/benchmarks). The most demanding cases like returning an array of 25 000 nested objects showed that in some cases it might be about 5 times slower. @@ -67,7 +67,7 @@ class Post { } ``` -This simple trick can speed up the execution up to 76%! The benchmarks show that using simple resolvers allows for as fast execution as with bare `graphql-js` - the measured overhead is only about ~13%, which is a much more reasonable value than 500%. Below you can see [the benchmarks results](https://github.com/MichalLytek/type-graphql/tree/master/benchmarks): +This simple trick can speed up the execution up to 76%! The benchmarks show that using simple resolvers allows for as fast execution as with bare `graphql-js` - the measured overhead is only about ~13%, which is a much more reasonable value than 500%. Below you can see [the benchmarks results](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/benchmarks): | | 25 000 array items | | ----------------------------------------------------------------------------- | :----------------: | diff --git a/website/versioned_docs/version-1.2.0-rc.1/resolvers.md b/website/versioned_docs/version-1.2.0-rc.1/resolvers.md index e399066b3..8ef289ac8 100644 --- a/website/versioned_docs/version-1.2.0-rc.1/resolvers.md +++ b/website/versioned_docs/version-1.2.0-rc.1/resolvers.md @@ -348,4 +348,4 @@ Resolver class `inheritance` is an advanced topic covered in the [resolver inher ## Examples These code samples are just made up for tutorial purposes. -You can find more advanced, real examples in the [examples folder on the repository](https://github.com/MichalLytek/type-graphql/tree/master/examples). +You can find more advanced, real examples in the [examples folder on the repository](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples). diff --git a/website/versioned_docs/version-1.2.0-rc.1/subscriptions.md b/website/versioned_docs/version-1.2.0-rc.1/subscriptions.md index 537f1ef4f..cd3c5178d 100644 --- a/website/versioned_docs/version-1.2.0-rc.1/subscriptions.md +++ b/website/versioned_docs/version-1.2.0-rc.1/subscriptions.md @@ -198,7 +198,7 @@ And it's done! We have a working GraphQL subscription server on `/subscriptions` ## Examples -See how subscriptions work in a [simple example](https://github.com/MichalLytek/type-graphql/tree/master/examples/simple-subscriptions). +See how subscriptions work in a [simple example](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/simple-subscriptions). -For production usage, it's better to use something more scalable like a Redis-based pubsub system - [a working example is also available](https://github.com/MichalLytek/type-graphql/tree/master/examples/redis-subscriptions). +For production usage, it's better to use something more scalable like a Redis-based pubsub system - [a working example is also available](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/redis-subscriptions). However, to launch this example you need to have a running instance of Redis and you might have to modify the example code to provide your connection parameters. diff --git a/website/versioned_docs/version-1.2.0-rc.1/unions.md b/website/versioned_docs/version-1.2.0-rc.1/unions.md index ce9bc4ec3..486271ebf 100644 --- a/website/versioned_docs/version-1.2.0-rc.1/unions.md +++ b/website/versioned_docs/version-1.2.0-rc.1/unions.md @@ -106,4 +106,4 @@ query { ## Examples -More advanced usage examples of unions (and enums) are located in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/master/examples/enums-and-unions). +More advanced usage examples of unions (and enums) are located in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/enums-and-unions). diff --git a/website/versioned_docs/version-1.2.0-rc.1/validation.md b/website/versioned_docs/version-1.2.0-rc.1/validation.md index ce790a06b..259d5db9a 100644 --- a/website/versioned_docs/version-1.2.0-rc.1/validation.md +++ b/website/versioned_docs/version-1.2.0-rc.1/validation.md @@ -177,7 +177,7 @@ Of course we can also create our own custom implementation of the `formatError` ### Example -To see how this works, check out the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/master/examples/automatic-validation). +To see how this works, check out the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/automatic-validation). ### Caveats @@ -218,4 +218,4 @@ const schema = await buildSchema({ ### Example -To see how this works, check out the [simple custom validation integration example](https://github.com/MichalLytek/type-graphql/tree/master/examples/custom-validation). +To see how this works, check out the [simple custom validation integration example](https://github.com/MichalLytek/type-graphql/tree/v1.2.0-rc.1/examples/custom-validation). diff --git a/website/versioned_docs/version-2.0.0-beta.3/authorization.md b/website/versioned_docs/version-2.0.0-beta.3/authorization.md new file mode 100644 index 000000000..c72b0cb0d --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/authorization.md @@ -0,0 +1,195 @@ +--- +title: Authorization +id: version-2.0.0-beta.3-authorization +original_id: authorization +--- + +Authorization is a core feature used in almost all APIs. Sometimes we want to restrict data access or actions for a specific group of users. + +In express.js (and other Node.js frameworks) we use middleware for this, like `passport.js` or the custom ones. However, in GraphQL's resolver architecture we don't have middleware so we have to imperatively call the auth checking function and manually pass context data to each resolver, which might be a bit tedious. + +That's why authorization is a first-class feature in `TypeGraphQL`! + +## How to use + +First, we need to use the `@Authorized` decorator as a guard on a field, query or mutation. +Example object type field guards: + +```ts +@ObjectType() +class MyObject { + @Field() + publicField: string; + + @Authorized() + @Field() + authorizedField: string; + + @Authorized("ADMIN") + @Field() + adminField: string; + + @Authorized(["ADMIN", "MODERATOR"]) + @Field({ nullable: true }) + hiddenField?: string; +} +``` + +We can leave the `@Authorized` decorator brackets empty or we can specify the role/roles that the user needs to possess in order to get access to the field, query or mutation. +By default the roles are of type `string` but they can easily be changed as the decorator is generic - `@Authorized(1, 7, 22)`. + +Thus, authorized users (regardless of their roles) can only read the `publicField` or the `authorizedField` from the `MyObject` object. They will receive `null` when accessing the `hiddenField` field and will receive an error (that will propagate through the whole query tree looking for a nullable field) for the `adminField` when they don't satisfy the role constraints. + +Sample query and mutation guards: + +```ts +@Resolver() +class MyResolver { + @Query() + publicQuery(): MyObject { + return { + publicField: "Some public data", + authorizedField: "Data for logged users only", + adminField: "Top secret info for admin", + }; + } + + @Authorized() + @Query() + authedQuery(): string { + return "Authorized users only!"; + } + + @Authorized("ADMIN", "MODERATOR") + @Mutation() + adminMutation(): string { + return "You are an admin/moderator, you can safely drop the database ;)"; + } +} +``` + +Authorized users (regardless of their roles) will be able to read data from the `publicQuery` and the `authedQuery` queries, but will receive an error when trying to perform the `adminMutation` when their roles don't include `ADMIN` or `MODERATOR`. + +Next, we need to create our auth checker function. Its implementation may depend on our business logic: + +```ts +export const customAuthChecker: AuthChecker = ( + { root, args, context, info }, + roles, +) => { + // Read user from context + // and check the user's permission against the `roles` argument + // that comes from the '@Authorized' decorator, eg. ["ADMIN", "MODERATOR"] + + return true; // or 'false' if access is denied +}; +``` + +The second argument of the `AuthChecker` generic type is `RoleType` - used together with the `@Authorized` decorator generic type. + +Auth checker can be also defined as a class - this way we can leverage the dependency injection mechanism: + +```ts +export class CustomAuthChecker implements AuthCheckerInterface { + constructor( + // Dependency injection + private readonly userRepository: Repository, + ) {} + + check({ root, args, context, info }: ResolverData, roles: string[]) { + const userId = getUserIdFromToken(context.token); + // Use injected service + const user = this.userRepository.getById(userId); + + // Custom logic, e.g.: + return user % 2 === 0; + } +} +``` + +The last step is to register the function or class while building the schema: + +```ts +import { customAuthChecker } from "../auth/custom-auth-checker.ts"; + +const schema = await buildSchema({ + resolvers: [MyResolver], + // Register the auth checking function + // or defining it inline + authChecker: customAuthChecker, +}); +``` + +And it's done! πŸ˜‰ + +If we need silent auth guards and don't want to return authorization errors to users, we can set the `authMode` property of the `buildSchema` config object to `"null"`: + +```ts +const schema = await buildSchema({ + resolvers: ["./**/*.resolver.ts"], + authChecker: customAuthChecker, + authMode: "null", +}); +``` + +It will then return `null` instead of throwing an authorization error. + +## Recipes + +We can also use `TypeGraphQL` with JWT authentication. +Here's an example using `@apollo/server`: + +```ts +import { ApolloServer } from "@apollo/server"; +import { expressMiddleware } from "@apollo/server/express4"; +import express from "express"; +import jwt from "express-jwt"; +import bodyParser from "body-parser"; +import { schema } from "./graphql/schema"; +import { User } from "./User.type"; + +// GraphQL path +const GRAPHQL_PATH = "/graphql"; + +// GraphQL context +type Context = { + user?: User; +}; + +// Express +const app = express(); + +// Apollo server +const server = new ApolloServer({ schema }); +await server.start(); + +// Mount a JWT or other authentication middleware that is run before the GraphQL execution +app.use( + GRAPHQL_PATH, + jwt({ + secret: "TypeGraphQL", + credentialsRequired: false, + }), +); + +// Apply GraphQL server middleware +app.use( + GRAPHQL_PATH, + bodyParser.json(), + expressMiddleware(server, { + // Build context + // 'req.user' comes from 'express-jwt' + context: async ({ req }) => ({ user: req.user }), + }), +); + +// Start server +await new Promise(resolve => app.listen({ port: 4000 }, resolve)); +console.log(`GraphQL server ready at http://localhost:4000/${GRAPHQL_PATH}`); +``` + +Then we can use standard, token based authorization in the HTTP header like in classic REST APIs and take advantage of the `TypeGraphQL` authorization mechanism. + +## Example + +See how this works in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/authorization). diff --git a/website/versioned_docs/version-2.0.0-beta.3/bootstrap.md b/website/versioned_docs/version-2.0.0-beta.3/bootstrap.md new file mode 100644 index 000000000..ce9f41d30 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/bootstrap.md @@ -0,0 +1,143 @@ +--- +title: Bootstrapping +id: version-2.0.0-beta.3-bootstrap +original_id: bootstrap +--- + +After creating our resolvers, type classes, and other business-related code, we need to make our app run. First we have to build the schema, then we can expose it with an HTTP server, WebSockets or even MQTT. + +## Create Executable Schema + +To create an executable schema from type and resolver definitions, we need to use the `buildSchema` function. +It takes a configuration object as a parameter and returns a promise of a `GraphQLSchema` object. + +In the configuration object we must provide a `resolvers` property, which is supposed to be an array of resolver classes: + +```ts +import { FirstResolver, SecondResolver } from "./resolvers"; +// ... +const schema = await buildSchema({ + resolvers: [FirstResolver, SecondResolver], +}); +``` + +Be aware that only operations (queries, mutation, etc.) defined in the resolvers classes (and types directly connected to them) will be emitted in schema. + +So if we have defined some object types (that implements an interface type [with disabled auto registering](./interfaces.md#registering-in-schema)) but are not directly used in other types definition (like a part of an union, a type of a field or a return type of an operation), we need to provide them manually in `orphanedTypes` options of `buildSchema`: + +```ts +import { FirstResolver, SecondResolver } from "../app/src/resolvers"; +import { FirstObject } from "../app/src/types"; +// ... +const schema = await buildSchema({ + resolvers: [FirstResolver, SecondResolver], + // Provide all the types that are missing in schema + orphanedTypes: [FirstObject], +}); +``` + +In case of defining the resolvers array somewhere else (not inline in the `buildSchema`), we need to use the `as const` syntax to inform the TS compiler and satisfy the `NonEmptyArray` constraints: + +```ts +// resolvers.ts +export const resolvers = [FirstResolver, SecondResolver] as const; + +// schema.ts +import { resolvers } from "./resolvers"; + +const schema = await buildSchema({ resolvers }); +``` + +There are also other options related to advanced features like [authorization](./authorization.md) or [validation](./validation.md) - you can read about them in docs. + +To make `await` work, we need to declare it as an async function. Example of `main.ts` file: + +```ts +import { buildSchema } from "type-graphql"; + +async function bootstrap() { + const schema = await buildSchema({ + resolvers: [ + // ... Resolvers classes + ], + }); + + // ... +} + +bootstrap(); // Actually run the async function +``` + +## Create an HTTP GraphQL endpoint + +In most cases, the GraphQL app is served by an HTTP server. After building the schema we can create the GraphQL endpoint with a variety of tools such as [`graphql-yoga`](https://github.com/dotansimha/graphql-yoga) or [`@apollo/server`](https://github.com/apollographql/apollo-server). + +Below is an example using [`@apollo/server`](https://github.com/apollographql/apollo-server): + +```ts +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; + +const PORT = process.env.PORT || 4000; + +async function bootstrap() { + // ... Build GraphQL schema + + // Create GraphQL server + const server = new ApolloServer({ schema }); + + // Start server + const { url } = await startStandaloneServer(server, { listen: { port: 4000 } }); + console.log(`GraphQL server ready at ${url}`); +} + +bootstrap(); +``` + +Remember to install the `@apollo/server` package from npm - it's not bundled with TypeGraphQL. + +Of course you can use the `express-graphql` middleware, `graphql-yoga` or whatever you want πŸ˜‰ + +## Create typeDefs and resolvers map + +TypeGraphQL provides a second way to generate the GraphQL schema - the `buildTypeDefsAndResolvers` function. + +It accepts the same `BuildSchemaOptions` as the `buildSchema` function but instead of an executable `GraphQLSchema`, it creates a typeDefs and resolversMap pair that you can use e.g. with [@graphql-tools/\*`](https://the-guild.dev/graphql/tools): + +```ts +import { makeExecutableSchema } from "@graphql-tools/schema"; + +const { typeDefs, resolvers } = await buildTypeDefsAndResolvers({ + resolvers: [FirstResolver, SecondResolver], +}); + +const schema = makeExecutableSchema({ typeDefs, resolvers }); +``` + +Or even with other libraries that expect the schema info in that shape, like [`apollo-link-state`](https://github.com/apollographql/apollo-link-state): + +```ts +import { withClientState } from "apollo-link-state"; + +const { typeDefs, resolvers } = await buildTypeDefsAndResolvers({ + resolvers: [FirstResolver, SecondResolver], +}); + +const stateLink = withClientState({ + // ... Other options like `cache` + typeDefs, + resolvers, +}); + +// ... Rest of `ApolloClient` initialization code +``` + +There's also a `sync` version of it - `buildTypeDefsAndResolversSync`: + +```ts +const { typeDefs, resolvers } = buildTypeDefsAndResolversSync({ + resolvers: [FirstResolver, SecondResolver], +}); +``` + +However, be aware that some of the TypeGraphQL features (i.a. [query complexity](./complexity.md)) might not work with the `buildTypeDefsAndResolvers` approach because they use some low-level `graphql-js` features. diff --git a/website/versioned_docs/version-2.0.0-beta.3/browser-usage.md b/website/versioned_docs/version-2.0.0-beta.3/browser-usage.md new file mode 100644 index 000000000..14fcffcf3 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/browser-usage.md @@ -0,0 +1,40 @@ +--- +title: Browser usage +id: version-2.0.0-beta.3-browser-usage +original_id: browser-usage +--- + +## Using classes in a client app + +Sometimes we might want to use the classes we've created and annotated with TypeGraphQL decorators, in our client app that works in the browser. For example, reusing the args or input classes with `class-validator` decorators or the object type classes with some helpful custom methods. + +Since TypeGraphQL is a Node.js framework, it doesn't work in a browser environment, so we may quickly get an error, e.g. `ERROR in ./node_modules/fs.realpath/index.js` or `utils1_promisify is not a function`, while trying to build our app with Webpack. To correct this, we have to configure Webpack to use the decorator shim instead of the normal module. We simply add this plugin code to our webpack config: + +```js +module.exports = { + // ... Rest of Webpack configuration + plugins: [ + // ... Other existing plugins + new webpack.NormalModuleReplacementPlugin(/type-graphql$/, resource => { + resource.request = resource.request.replace(/type-graphql/, "type-graphql/dist/browser-shim.js"); + }), + ]; +} +``` + +In case of cypress, you can adapt the same webpack config trick just by applying the [cypress-webpack-preprocessor](https://github.com/cypress-io/cypress-webpack-preprocessor) plugin. + +However, in some TypeScript projects like the ones using Angular, which AoT compiler requires that a full `*.ts` file is provided instead of just a `*.js` and `*.d.ts` files, to use this shim we have to simply set up our TypeScript configuration in `tsconfig.json` to use this file instead of a normal TypeGraphQL module: + +```json +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "type-graphql": ["./node_modules/type-graphql/dist/browser-shim.ts"] + } + } +} +``` + +Thanks to this, our bundle will be much lighter as we don't need to embed the whole TypeGraphQL library code in our app. diff --git a/website/versioned_docs/version-2.0.0-beta.3/complexity.md b/website/versioned_docs/version-2.0.0-beta.3/complexity.md new file mode 100644 index 000000000..d50e2f3c7 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/complexity.md @@ -0,0 +1,103 @@ +--- +title: Query complexity +id: version-2.0.0-beta.3-complexity +original_id: complexity +--- + +A single GraphQL query can potentially generate a huge workload for a server, like thousands of database operations which can be used to cause DDoS attacks. In order to limit and keep track of what each GraphQL operation can do, `TypeGraphQL` provides the option of integrating with Query Complexity tools like [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity). + +This cost analysis-based solution is very promising, since we can define a β€œcost” per field and then analyze the AST to estimate the total cost of the GraphQL query. Of course all the analysis is handled by `graphql-query-complexity`. + +All we must do is define our complexity cost for the fields, mutations or subscriptions in `TypeGraphQL` and implement `graphql-query-complexity` in whatever GraphQL server that is being used. + +## How to use + +First, we need to pass `complexity` as an option to the decorator on a field, query or mutation. + +Example of complexity + +```ts +@ObjectType() +class MyObject { + @Field({ complexity: 2 }) + publicField: string; + + @Field({ complexity: ({ args, childComplexity }) => childComplexity + 1 }) + complexField: string; +} +``` + +The `complexity` option may be omitted if the complexity value is 1. +Complexity can be passed as an option to any `@Field`, `@FieldResolver`, `@Mutation` or `@Subscription` decorator. If both `@FieldResolver` and `@Field` decorators of the same property have complexity defined, then the complexity passed to the field resolver decorator takes precedence. + +In the next step, we will integrate `graphql-query-complexity` with the server that expose our GraphQL schema over HTTP. +You can use it with `express-graphql` like [in the lib examples](https://github.com/slicknode/graphql-query-complexity/blob/b6a000c0984f7391f3b4e886e3df6a7ed1093b07/README.md#usage-with-express-graphql), however we will use Apollo Server like in our other examples: + +```ts +async function bootstrap() { + // ... Build GraphQL schema + + // Create GraphQL server + const server = new ApolloServer({ + schema, + // Create a plugin to allow query complexity calculation for every request + plugins: [ + { + requestDidStart: async () => ({ + async didResolveOperation({ request, document }) { + /** + * Provides GraphQL query analysis to be able to react on complex queries to the GraphQL server + * It can be used to protect the GraphQL server against resource exhaustion and DoS attacks + * More documentation can be found at https://github.com/ivome/graphql-query-complexity + */ + const complexity = getComplexity({ + // GraphQL schema + schema, + // To calculate query complexity properly, + // check only the requested operation + // not the whole document that may contains multiple operations + operationName: request.operationName, + // GraphQL query document + query: document, + // GraphQL query variables + variables: request.variables, + // Add any number of estimators. The estimators are invoked in order, the first + // numeric value that is being returned by an estimator is used as the field complexity + // If no estimator returns a value, an exception is raised + estimators: [ + // Using fieldExtensionsEstimator is mandatory to make it work with type-graphql + fieldExtensionsEstimator(), + // Add more estimators here... + // This will assign each field a complexity of 1 + // if no other estimator returned a value + simpleEstimator({ defaultComplexity: 1 }), + ], + }); + + // React to the calculated complexity, + // like compare it with max and throw error when the threshold is reached + if (complexity > MAX_COMPLEXITY) { + throw new Error( + `Sorry, too complicated query! ${complexity} exceeded the maximum allowed complexity of ${MAX_COMPLEXITY}`, + ); + } + console.log("Used query complexity points:", complexity); + }, + }), + }, + ], + }); + + // Start server + const { url } = await startStandaloneServer(server, { listen: { port: 4000 } }); + console.log(`GraphQL server ready at ${url}`); +} +``` + +And it's done! πŸ˜‰ + +For more info about how query complexity is computed, please visit [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity). + +## Example + +See how this works in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/query-complexity). diff --git a/website/versioned_docs/version-2.0.0-beta.3/custom-decorators.md b/website/versioned_docs/version-2.0.0-beta.3/custom-decorators.md new file mode 100644 index 000000000..829eb22d5 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/custom-decorators.md @@ -0,0 +1,109 @@ +--- +title: Custom decorators +id: version-2.0.0-beta.3-custom-decorators +original_id: custom-decorators +--- + +Custom decorators are a great way to reduce the boilerplate and reuse some common logic between different resolvers. TypeGraphQL supports two kinds of custom decorators - method and parameter. + +## Method decorators + +Using [middlewares](./middlewares.md) allows to reuse some code between resolvers. To further reduce the boilerplate and have a nicer API, we can create our own custom method decorators. + +They work in the same way as the [reusable middleware function](./middlewares.md#reusable-middleware), however, in this case we need to call `createMethodDecorator` helper function with our middleware logic and return its value: + +```ts +export function ValidateArgs(schema: JoiSchema) { + return createMethodDecorator(async ({ args }, next) => { + // Middleware code that uses custom decorator arguments + + // e.g. Validation logic based on schema using 'joi' + await joiValidate(schema, args); + return next(); + }); +} +``` + +The usage is then very simple, as we have a custom, descriptive decorator - we just place it above the resolver/field and pass the required arguments to it: + +```ts +@Resolver() +export class RecipeResolver { + @ValidateArgs(MyArgsSchema) // Custom decorator + @UseMiddleware(ResolveTime) // Explicit middleware + @Query() + randomValue(@Args() { scale }: MyArgs): number { + return Math.random() * scale; + } +} +``` + +## Parameter decorators + +Parameter decorators are just like the custom method decorators or middlewares but with an ability to return some value that will be injected to the method as a parameter. Thanks to this, it reduces the pollution in `context` which was used as a workaround for the communication between reusable middlewares and resolvers. + +They might be just a simple data extractor function, that makes our resolver more unit test friendly: + +```ts +function CurrentUser() { + return createParamDecorator(({ context }) => context.currentUser); +} +``` + +Or might be a more advanced one that performs some calculations and encapsulates some logic. Compared to middlewares, they allows for a more granular control on executing the code, like calculating fields map based on GraphQL info only when it's really needed (requested by using the `@Fields()` decorator): + +```ts +function Fields(level = 1): ParameterDecorator { + return createParamDecorator(async ({ info }) => { + const fieldsMap: FieldsMap = {}; + // Calculate an object with info about requested fields + // based on GraphQL 'info' parameter of the resolver and the level parameter + // or even call some async service, as it can be a regular async function and we can just 'await' + return fieldsMap; + }); +} +``` + +> Be aware, that `async` function as a custom param decorators logic can make the GraphQL resolver execution slower, so try to avoid them, if possible. + +Then we can use our custom param decorators in the resolvers just like the built-in decorators: + +```ts +@Resolver() +export class RecipeResolver { + constructor(private readonly recipesRepository: Repository) {} + + @Authorized() + @Mutation(returns => Recipe) + async addRecipe( + @Args() recipeData: AddRecipeInput, + // Custom decorator just like the built-in one + @CurrentUser() currentUser: User, + ) { + const recipe: Recipe = { + ...recipeData, + // and use the data returned from custom decorator in the resolver code + author: currentUser, + }; + await this.recipesRepository.save(recipe); + + return recipe; + } + + @Query(returns => Recipe, { nullable: true }) + async recipe( + @Arg("id") id: string, + // Custom decorator that parses the fields from GraphQL query info + @Fields() fields: FieldsMap, + ) { + return await this.recipesRepository.find(id, { + // use the fields map as a select projection to optimize db queries + select: fields, + }); + } +} +``` + +## Example + +See how different kinds of custom decorators work in the [custom decorators and middlewares example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/middlewares-custom-decorators). diff --git a/website/versioned_docs/version-2.0.0-beta.3/dependency-injection.md b/website/versioned_docs/version-2.0.0-beta.3/dependency-injection.md new file mode 100644 index 000000000..70638033d --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/dependency-injection.md @@ -0,0 +1,180 @@ +--- +title: Dependency injection +id: version-2.0.0-beta.3-dependency-injection +original_id: dependency-injection +--- + +Dependency injection is a really useful pattern that helps in decoupling parts of the app. + +TypeGraphQL supports this technique by allowing users to provide their IoC container that will be used by the framework. + +## Basic usage + +The usage of this feature is very simple - all you need to do is register a 3rd party container. + +Example using TypeDI: + +```ts +import { buildSchema } from "type-graphql"; +// IOC container +import { Container } from "typedi"; +import { SampleResolver } from "./resolvers"; + +// Build TypeGraphQL executable schema +const schema = await buildSchema({ + // Array of resolvers + resolvers: [SampleResolver], + // Registry 3rd party IOC container + container: Container, +}); +``` + +Resolvers will then be able to declare their dependencies and TypeGraphQL will use the container to solve them: + +```ts +import { Service } from "typedi"; + +@Service() +@Resolver(of => Recipe) +export class RecipeResolver { + constructor( + // Dependency injection + private readonly recipeService: RecipeService, + ) {} + + @Query(returns => Recipe, { nullable: true }) + async recipe(@Arg("recipeId") recipeId: string) { + // Usage of the injected service + return this.recipeService.getOne(recipeId); + } +} +``` + +A sample recipe service implementation may look like this: + +```ts +import { Service, Inject } from "typedi"; + +@Service() +export class RecipeService { + @Inject("SAMPLE_RECIPES") + private readonly items: Recipe[], + + async getAll() { + return this.items; + } + + async getOne(id: string) { + return this.items.find(item => item.id === id); + } +} +``` + +> Be aware than when you use [InversifyJS](https://github.com/inversify/InversifyJS), you have to bind the resolver class with the [self-binding of concrete types](https://github.com/inversify/InversifyJS/blob/master/wiki/classes_as_id.md#self-binding-of-concrete-types), e.g.: +> +> ```ts +> container.bind(SampleResolver).to(SampleResolver).inSingletonScope(); +> ``` + +## Scoped containers + +Dependency injection is a really powerful pattern, but some advanced users may encounter the need for creating fresh instances of some services or resolvers for every request. Since `v0.13.0`, **TypeGraphQL** supports this feature, that is extremely useful for tracking logs by individual requests or managing stateful services. + +To register a scoped container, we need to make some changes in the server bootstrapping config code. +First we need to provide a container resolver function. It takes the resolver data (like context) as an argument and should return an instance of the container scoped to the request. + +For simple container libraries we may define it inline, e.g. using `TypeDI`: + +```ts +await buildSchema({ + container: (({ context }: ResolverData) => Container.of(context.requestId)); +}; +``` + +The tricky part is where the `context.requestId` comes from. Unfortunately, we need to provide it manually using hooks that are exposed by HTTP GraphQL middleware like `express-graphql`, `@apollo/server` or `graphql-yoga`. + +For some other advanced libraries, we might need to create an instance of the container, place it in the context object and then retrieve it in the `container` getter function: + +```ts +await buildSchema({ + container: (({ context }: ResolverData) => context.container); +}; +``` + +Example using `TypeDI` and `@apollo/server` with the `context` creation method: + +```ts +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { Container } from "typedi"; + +// Create GraphQL server +const server = new ApolloServer({ + // GraphQL schema + schema, +}); + +// Start server +const { url } = await startStandaloneServer(server, { + listen: { port: 4000 }, + // Provide unique context with 'requestId' for each request + context: async () => { + const requestId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // uuid-like + const container = Container.of(requestId.toString()); // Get scoped container + const context = { requestId, container }; // Create context + container.set("context", context); // Set context or other data in container + + return context; + }, +}); +console.log(`GraphQL server ready at ${url}`); +``` + +We also have to dispose the container after the request has been handled and the response is ready. Otherwise, there would be a huge memory leak as the new instances of services and resolvers have been created for each request but they haven't been cleaned up. + +Apollo Server has a [plugins](https://www.apollographql.com/docs/apollo-server/integrations/plugins) feature that supports [`willSendResponse`](https://www.apollographql.com/docs/apollo-server/integrations/plugins/#willsendresponse) lifecycle event. We can leverage it to clean up the container after handling the request. + +Example using `TypeDI` and `@apollo/server` with plugins approach: + +```ts +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { Container } from "typedi"; + +const server = new ApolloServer({ + // GraphQL schema + schema, + // Create a plugin to allow for disposing the scoped container created for every request + plugins: [ + { + requestDidStart: async () => ({ + async willSendResponse(requestContext) { + // Dispose the scoped container to prevent memory leaks + Container.reset(requestContext.contextValue.requestId.toString()); + + // For developers curiosity purpose, here is the logging of current scoped container instances + // Make multiple parallel requests to see in console how this works + const instancesIds = ((Container as any).instances as ContainerInstance[]).map( + instance => instance.id, + ); + console.log("Instances left in memory: ", instancesIds); + }, + }), + }, + ], +}); +``` + +And basically that's it! The configuration of the container is done and TypeGraphQL will be able to use different instances of resolvers for each request. + +The only thing that's left is the container configuration - we need to check out the docs for our container library (`InversifyJS`, `injection-js`, `TypeDI` or other) to get know how to setup the lifetime of the injectable objects (transient, scoped or singleton). + +> Be aware that some libraries (like `TypeDI`) by default create new instances for every scoped container, so you might experience a **significant increase in memory usage** and some slowing down in query resolving speed, so please be careful with using this feature! + +## Example + +You can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/using-container). + +For a more advanced usage example with scoped containers, check out [advanced example with scoped containers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/using-scoped-container). + +Integration with [TSyringe](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/tsyringe). diff --git a/website/versioned_docs/version-2.0.0-beta.3/directives.md b/website/versioned_docs/version-2.0.0-beta.3/directives.md new file mode 100644 index 000000000..c972e0843 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/directives.md @@ -0,0 +1,131 @@ +--- +title: Directives +id: version-2.0.0-beta.3-directives +original_id: directives +--- + +> A directive is an identifier preceded by a `@` character, optionally followed by a list of named arguments, which can appear after almost any form of syntax in the GraphQL query or schema languages. + +Though the [GraphQL directives](https://www.apollographql.com/docs/graphql-tools/schema-directives) syntax is similar to TS decorators, they are purely an SDL (Schema Definition Language) feature that allows you to add metadata to a selected type or its field: + +```graphql +type Foo @auth(requires: USER) { + field: String! +} + +type Bar { + field: String! @auth(requires: USER) +} +``` + +That metadata can be read at runtime to modify the structure and behavior of a GraphQL schema to support reusable code and tasks like authentication, permission, formatting, and plenty more. They are also really useful for some external services like [Apollo Cache Control](https://www.apollographql.com/docs/apollo-server/performance/caching/#adding-cache-hints-statically-in-your-schema) or [Apollo Federation](https://www.apollographql.com/docs/apollo-server/federation/introduction/#federated-schema-example). + +**TypeGraphQL** of course provides some basic support for using the schema directives via the `@Directive` decorator. + +## Usage + +### Declaring in schema + +Basically, we declare the usage of directives just like in SDL, with the `@` syntax: + +```ts +@Directive('@deprecated(reason: "Use newField")') +``` + +Currently, you can use the directives only on object types, input types, interface types and their fields or fields resolvers, as well as queries, mutations and subscriptions. Other locations like scalars, enums, unions or arguments are not yet supported. + +So the `@Directive` decorator can be placed over the class property/method or over the type class itself, depending on the needs and the placements supported by the implementation: + +```ts +@Directive("@auth(requires: USER)") +@ObjectType() +class Foo { + @Field() + field: string; +} + +@ObjectType() +class Bar { + @Directive("@auth(requires: USER)") + @Field() + field: string; +} + +@Resolver(of => Foo) +class FooBarResolver { + @Directive("@auth(requires: ANY)") + @Query() + foobar(@Arg("baz") baz: string): string { + return "foobar"; + } + + @Directive("@auth(requires: ADMIN)") + @FieldResolver() + bar(): string { + return "foobar"; + } +} +``` + +> Note that even as directives are a purely SDL thing, they won't appear in the generated schema definition file. Current implementation of directives in TypeGraphQL is using some crazy workarounds because [`graphql-js` doesn't support setting them by code](https://github.com/graphql/graphql-js/issues/1343) and the built-in `printSchema` utility omits the directives while printing. See [emit schema with custom directives](./emit-schema.md#emit-schema-with-custom-directives) for more info. + +Also please note that `@Directive` can only contain a single GraphQL directive name or declaration. If you need to have multiple directives declared, just place multiple decorators: + +```ts +@ObjectType() +class Foo { + @Directive("@lowercase") + @Directive('@deprecated(reason: "Use `newField`")') + @Directive("@hasRole(role: Manager)") + @Field() + bar: string; +} +``` + +### Providing the implementation + +Besides declaring the usage of directives, you also have to register the runtime part of the used directives. + +> Be aware that TypeGraphQL doesn't have any special way for implementing schema directives. You should use some [3rd party libraries](https://the-guild.dev/graphql/tools/docs/schema-directives#implementing-schema-directives) depending on the tool set you use in your project, e.g. `@graphql-tools/*` or `ApolloServer`. + +If you write your custom GraphQL directive or import a package that exports a `GraphQLDirective` instance, you need to register the directives definitions in the `buildSchema` options: + +```ts +// Build TypeGraphQL executable schema +const tempSchema = await buildSchema({ + resolvers: [SampleResolver], + // Register the directives definitions + directives: [myDirective], +}); +``` + +Then you need to apply the schema transformer for your directive, that implements the desired logic of your directive: + +```ts +// Transform and obtain the final schema +const schema = myDirectiveTransformer(tempSchema); +``` + +If the directive package used by you exports a string-based `typeDefs`, you need to add those typedefs to the schema and then apply directive transformer. + +Here is an example using the [`@graphql-tools/*`](https://the-guild.dev/graphql/tools): + +```ts +import { mergeSchemas } from "@graphql-tools/schema"; +import { renameDirective } from "fake-rename-directive-package"; + +// Build TypeGraphQL executable schema +const schemaSimple = await buildSchema({ + resolvers: [SampleResolver], +}); + +// Merge schema with sample directive type definitions +const schemaMerged = mergeSchemas({ + schemas: [schemaSimple], + // Register the directives definitions + typeDefs: [renameDirective.typeDefs], +}); + +// Transform and obtain the final schema +const schema = renameDirective.transformer(schemaMerged); +``` diff --git a/website/versioned_docs/version-2.0.0-beta.3/emit-schema.md b/website/versioned_docs/version-2.0.0-beta.3/emit-schema.md new file mode 100644 index 000000000..7557922b7 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/emit-schema.md @@ -0,0 +1,66 @@ +--- +title: Emitting the schema SDL +id: version-2.0.0-beta.3-emit-schema +original_id: emit-schema +--- + +TypeGraphQL's main feature is creating the schema using only TypeScript classes and decorators. However, there might be a need for the schema to be printed into a `schema.graphql` file and there are plenty of reasons for that. Mainly, the schema SDL file is needed for GraphQL ecosystem tools that perform client-side queries autocompletion and validation. Some developers also may want to use it as a kind of snapshot for detecting schema regression or they just prefer to read the SDL file to explore the API instead of reading the complicated TypeGraphQL-based app code, navigating through the GraphiQL or GraphQL Playground. To accomplish this demand, TypeGraphQL allows you to create a schema definition file in two ways. + +The first one is to generate it automatically on every build of the schema - just pass `emitSchemaFile: true` to the `buildSchema` options in order to emit the `schema.graphql` in the root of the project's working directory. You can also manually specify the path and the file name where the schema definition should be written or even specify `PrintSchemaOptions` to configure the look and format of the schema definition. + +```ts +const schema = await buildSchema({ + resolvers: [ExampleResolver], + // Automatically create `schema.graphql` file with schema definition in project's working directory + emitSchemaFile: true, + // Or create the file with schema in selected path + emitSchemaFile: path.resolve(__dirname, "__snapshots__/schema/schema.graphql"), + // Or pass a config object + emitSchemaFile: { + path: __dirname + "/schema.graphql", + sortedSchema: false, // By default the printed schema is sorted alphabetically + }, +}); +``` + +The second way to emit the schema definition file is by doing it programmatically. We would use the `emitSchemaDefinitionFile` function (or it's sync version `emitSchemaDefinitionFileSync`) and pass in the path, along with the schema object. We can use this among others as part of a testing script that checks if the snapshot of the schema definition is correct or to automatically generate it on every file change during local development. + +```ts +import { emitSchemaDefinitionFile } from "type-graphql"; + +// ... +hypotheticalFileWatcher.watch("./src/**/*.{resolver,type,input,arg}.ts", async () => { + const schema = getSchemaNotFromBuildSchemaFunction(); + await emitSchemaDefinitionFile("/path/to/folder/schema.graphql", schema); +}); +``` + +### Emit schema with custom directives + +Currently TypeGraphQL does not directly support emitting the schema with custom directives due to `printSchema` function limitations from `graphql-js`. + +If we want the custom directives to appear in the generated schema definition file we have to create a custom function that use a third-party `printSchema` function. + +Below there is an example that uses the `printSchemaWithDirectives` function from [`@graphql-tools/utils`](https://www.graphql-tools.com/docs/api/modules/utils): + +```ts +import { GraphQLSchema, lexicographicSortSchema } from "graphql"; +import { printSchemaWithDirectives } from "@graphql-tools/utils"; +import { outputFile } from "type-graphql/dist/helpers/filesystem"; + +export async function emitSchemaDefinitionWithDirectivesFile( + schemaFilePath: string, + schema: GraphQLSchema, +): Promise { + const schemaFileContent = printSchemaWithDirectives(lexicographicSortSchema(schema)); + await outputFile(schemaFilePath, schemaFileContent); +} +``` + +The usage of `emitSchemaDefinitionWithDirectivesFile` function is the same as with standard `emitSchemaDefinitionFile`: + +```ts +const schema = await buildSchema(/*...*/); + +await emitSchemaDefinitionWithDirectivesFile("/path/to/folder/schema.graphql", schema); +``` diff --git a/website/versioned_docs/version-2.0.0-beta.3/enums.md b/website/versioned_docs/version-2.0.0-beta.3/enums.md new file mode 100644 index 000000000..498e9ff0a --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/enums.md @@ -0,0 +1,143 @@ +--- +title: Enums +id: version-2.0.0-beta.3-enums +original_id: enums +--- + +Nowadays almost all typed languages have support for enumerated types, including TypeScript. Enums limit the range of a variable's values to a set of predefined constants, which makes it easier to document intent. + +GraphQL also has enum type support, so TypeGraphQL allows us to use TypeScript enums in our GraphQL schema. + +## Creating enum + +Let's create a TypeScript enum. It can be a numeric or string enum - the internal values of enums are taken from the enum definition values and the public names taken from the enum keys: + +```ts +// Implicit value 0, 1, 2, 3 +enum Direction { + UP, + DOWN, + LEFT, + RIGHT, +} + +// Or explicit values +enum Direction { + UP = "UP", + DOWN = "DOWN", + LEFT = "LEFT", + RIGHT = "RIGHT", +} +``` + +To tell TypeGraphQL about our enum, we would ideally mark the enums with the `@EnumType()` decorator. However, TypeScript decorators only work with classes, so we need to make TypeGraphQL aware of the enums manually by calling the `registerEnumType` function and providing the enum name for GraphQL: + +```ts +import { registerEnumType } from "type-graphql"; + +registerEnumType(Direction, { + name: "Direction", // Mandatory + description: "The basic directions", // Optional +}); +``` + +In case we need to provide additional GraphQL-related config for values, like description or deprecation reason, we can use `valuesConfig` property and put the data inside it, e.g.: + +```ts +enum Direction { + UP = "UP", + DOWN = "DOWN", + LEFT = "LEFT", + RIGHT = "RIGHT", + SIDEWAYS = "SIDEWAYS", +} + +registerEnumType(Direction, { + name: "Direction", + description: "The basic directions", + valuesConfig: { + SIDEWAYS: { + deprecationReason: "Replaced with Left or Right", + }, + RIGHT: { + description: "The other left", + }, + }, +}); +``` + +This way, the additional info will be emitted in the GraphQL schema: + +```graphql +enum Direction { + UP + DOWN + LEFT + """ + The other left + """ + RIGHT + SIDEWAYS @deprecated(reason: "Replaced with Left or Right") +} +``` + +## Using enum + +The last step is very important: TypeScript has limited reflection ability, so this is a case where we have to explicitly provide the enum type for object type fields, input type fields, args, and the return type of queries and mutations: + +```ts +@InputType() +class JourneyInput { + @Field(type => Direction) // Mandatory + direction: Direction; +} +``` + +Without this annotation, the generated GQL type would be `String` or `Float` (depending on the enum type), rather than the `ENUM` we are aiming for. + +With all that in place, we can use our enum directly in our code πŸ˜‰ + +```ts +@Resolver() +class SpriteResolver { + private sprite = getMarioSprite(); + + @Mutation() + move(@Arg("direction", type => Direction) direction: Direction): boolean { + switch (direction) { + case Direction.Up: + this.sprite.position.y++; + break; + case Direction.Down: + this.sprite.position.y--; + break; + case Direction.Left: + this.sprite.position.x--; + break; + case Direction.Right: + this.sprite.position.x++; + break; + default: + // Never reached + return false; + } + + return true; + } +} +``` + +## Interoperability + +Enums in TypeGraphQL are designed with server side in mind - the runtime will map the string value from input into a corresponding enum value, like `"UP"` into `0`. While this is very handy e.g. for mapping database values into GraphQL API enum names, it makes it unusable on the query side because `Direction.UP` will put `0` in the query which is an invalid value (should be `UP`). + +So if we would like to share the types definition and use the enum on the client side app or use the enums directly on the server app e.g. in tests, we have to use the direct mapping of the enum member names with values, e.g.: + +```ts +enum Direction { + UP = "UP", + DOWN = "DOWN", + LEFT = "LEFT", + RIGHT = "RIGHT", +} +``` diff --git a/website/versioned_docs/version-2.0.0-beta.3/esm.md b/website/versioned_docs/version-2.0.0-beta.3/esm.md new file mode 100644 index 000000000..70d110d0a --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/esm.md @@ -0,0 +1,48 @@ +--- +title: ECMAScript Modules +id: version-2.0.0-beta.3-esm +original_id: esm +--- + +Since `v2.0.0` release, TypeGraphQL is compatible with ECMAScript modules. + +Thanks to this, we can `import` the `type-graphql` package in the ESM projects without any hassle. + +## TypeScript configuration + +It's important to properly configure the project, so that it uses ESM correctly: + +- the `module` options should be set to `ES2020/ES2022/ESNext` +- for the NodeJS apps, we should set `moduleResolution` to `"node16"` + +All in all, the `tsconfig.json` file should looks like this: + +```json title="tsconfig.json" +{ + "compilerOptions": { + "target": "es2021", + "module": "es2020", + "moduleResolution": "node16", + "experimentalDecorators": true, + "emitDecoratorMetadata": true + } +} +``` + +## Package.json configuration + +It is also important to set `type` option to `"module"` in your `package.json` file: + +```json title="package.json" +{ + "type": "module" +} +``` + +## Imports + +Apart from using `import` syntax, your local imports have to use the `.js` suffix, e.g.: + +```ts +import { MyResolver } from "./resolvers/MyResolver.js"; +``` diff --git a/website/versioned_docs/version-2.0.0-beta.3/examples.md b/website/versioned_docs/version-2.0.0-beta.3/examples.md new file mode 100644 index 000000000..ce7987bf4 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/examples.md @@ -0,0 +1,52 @@ +--- +title: Examples +sidebar_label: List of examples +id: version-2.0.0-beta.3-examples +original_id: examples +--- + +On the [GitHub repository](https://github.com/MichalLytek/type-graphql) there are a few simple [`examples`](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples) of how to use different `TypeGraphQL` features and how well they integrate with 3rd party libraries. + +To run an example, simply go to the subdirectory (e.g. `cd ./simple-usage`), and then start the server (`npx ts-node ./index.ts`). + +Each subdirectory contains a `examples.graphql` file with predefined GraphQL queries/mutations/subscriptions that you can use in Apollo Studio () and play with them by modifying their shape and data. + +## Basics + +- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/simple-usage) + +## Advanced + +- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/enums-and-unions) +- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/simple-subscriptions) +- [Subscriptions (using Redis) \*\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/redis-subscriptions) +- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/interfaces-inheritance) +- [Extensions (metadata)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/extensions) + +## Features usage + +- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/using-container) + - [Scoped containers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/using-scoped-container) +- [Authorization](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/authorization) +- [Validation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/automatic-validation) + - [Custom validation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/custom-validation) +- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/interfaces-inheritance) +- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/resolvers-inheritance) +- [Generic types](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/generic-types) +- [Mixin classes](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/mixin-classes) +- [Middlewares and Custom Decorators](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/middlewares-custom-decorators) +- [Query complexity](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/query-complexity) + +## 3rd party libs integration + +- [TypeORM (manual, synchronous) \*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/typeorm-basic-usage) +- [TypeORM (automatic, lazy relations) \*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/typeorm-lazy-relations) +- [MikroORM \*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/mikro-orm) +- [Typegoose \*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/typegoose) +- [Apollo federation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/apollo-federation) +- [Apollo Cache Control](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/apollo-cache) +- [GraphQL Scalars](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/graphql-scalars) +- [TSyringe](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/tsyringe) + +_\* Note that we need to provide the environment variable `DATABASE_URL` with connection parameters to your local database_ \ +_\*\* Note that we need to provide the environment variable `REDIS_URL` with connection parameters to your local Redis instance_ diff --git a/website/versioned_docs/version-2.0.0-beta.3/extensions.md b/website/versioned_docs/version-2.0.0-beta.3/extensions.md new file mode 100644 index 000000000..90f7b0a29 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/extensions.md @@ -0,0 +1,119 @@ +--- +title: Extensions +id: version-2.0.0-beta.3-extensions +original_id: extensions +--- + +The `graphql-js` library allows for putting arbitrary data into GraphQL types config inside the `extensions` property. +Annotating schema types or fields with a custom metadata, that can be then used at runtime by middlewares or resolvers, is a really powerful and useful feature. + +For such use cases, **TypeGraphQL** provides the `@Extensions` decorator, which adds the data we defined to the `extensions` property of the executable schema for the decorated classes, methods or properties. + +> Be aware that this is a low-level decorator and you generally have to provide your own logic to make use of the `extensions` metadata. + +## Using the `@Extensions` decorator + +Adding extensions to the schema type is as simple as using the `@Extensions` decorator and passing it an object of the custom data we want: + +```ts +@Extensions({ complexity: 2 }) +``` + +We can pass several fields to the decorator: + +```ts +@Extensions({ logMessage: "Restricted access", logLevel: 1 }) +``` + +And we can also decorate a type several times. The snippet below shows that this attaches the exact same extensions data to the schema type as the snippet above: + +```ts +@Extensions({ logMessage: "Restricted access" }) +@Extensions({ logLevel: 1 }) +``` + +If we decorate the same type several times with the same extensions key, the one defined at the bottom takes precedence: + +```ts +@Extensions({ logMessage: "Restricted access" }) +@Extensions({ logMessage: "Another message" }) +``` + +The above usage results in your GraphQL type having a `logMessage: "Another message"` property in its extensions. + +TypeGraphQL classes with the following decorators can be annotated with `@Extensions` decorator: + +- `@ObjectType` +- `@InputType` +- `@Field` +- `@Query` +- `@Mutation` +- `@FieldResolver` + +So the `@Extensions` decorator can be placed over the class property/method or over the type class itself, and multiple times if necessary, depending on what we want to do with the extensions data: + +```ts +@Extensions({ roles: ["USER"] }) +@ObjectType() +class Foo { + @Field() + field: string; +} + +@ObjectType() +class Bar { + @Extensions({ roles: ["USER"] }) + @Field() + field: string; +} + +@ObjectType() +class Bar { + @Extensions({ roles: ["USER"] }) + @Extensions({ visible: false, logMessage: "User accessed restricted field" }) + @Field() + field: string; +} + +@Resolver(of => Foo) +class FooBarResolver { + @Extensions({ roles: ["USER"] }) + @Query() + foobar(@Arg("baz") baz: string): string { + return "foobar"; + } + + @Extensions({ roles: ["ADMIN"] }) + @FieldResolver() + bar(): string { + return "foobar"; + } +} +``` + +## Using the extensions data in runtime + +Once we have decorated the necessary types with extensions, the executable schema will contain the extensions data, and we can make use of it in any way we choose. The most common use will be to read it at runtime in resolvers or middlewares and perform some custom logic there. + +Here is a simple example of a global middleware that will be logging a message on field resolver execution whenever the field is decorated appropriately with `@Extensions`: + +```ts +export class LoggerMiddleware implements MiddlewareInterface { + constructor(private readonly logger: Logger) {} + + use({ info }: ResolverData, next: NextFn) { + // extract `extensions` object from GraphQLResolveInfo object to get the `logMessage` value + const { logMessage } = info.parentType.getFields()[info.fieldName].extensions || {}; + + if (logMessage) { + this.logger.log(logMessage); + } + + return next(); + } +} +``` + +## Examples + +You can see more detailed examples of usage [here](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/extensions). diff --git a/website/versioned_docs/version-2.0.0-beta.3/faq.md b/website/versioned_docs/version-2.0.0-beta.3/faq.md new file mode 100644 index 000000000..ab1ab30ef --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/faq.md @@ -0,0 +1,93 @@ +--- +title: Frequently Asked Questions +id: version-2.0.0-beta.3-faq +original_id: faq +--- + +## Resolvers + +### Should I implement a field resolver as an object type getter, a method or a resolver class method? + +This depends on various factors: + +- if the resolver only needs access to the root/object value - use a getter +- if the field has arguments + - and must perform side effects e.g. a database call - use a resolver class method and leverage the dependency injection mechanism + - otherwise, use object type methods (pure functions, calculations based on object values and arguments) +- if the business logic must be separated from the type definition - use a resolver class method + +### Are there any global error handlers to catch errors from resolvers or services? + +Use middleware for this purpose - just wrap `await next()` in a try-catch block then register it as the first global middleware. + +### Why did I receive this error? `GraphQLError: Expected value of type "MyType" but got: [object Object]` + +This error occurs when the resolver (query, mutation, field) type is an interface/union and a plain object is returned from it. +In this case, what should be returned is an instance of the selected object type class in the resolver. +Otherwise, `graphql-js` will not be able to correctly detect the underlying GraphQL type. + +## Bootstrapping + +### How do I fix this error? `Cannot use GraphQLSchema "[object Object]" from another module or realm` + +This error occurs mostly when there are more than one version of the `graphql-js` module in the project. +In most cases it means that one of our dependencies has a dependency on a different version of `graphql-js`, e.g. we, or TypeGraphQL use `v14.0.2` but `apollo-server-express` depends on `v0.13.2`. +We can print the dependency tree by running `npm ls graphql` (or the yarn equivalent) to find the faulty dependencies. +Then we should update or downgrade them until they all match the semver on `graphql`, e.g. `^14.0.0`. +Dependencies may also need to be flattened, so that they all share a single instance of the `graphql` module in the `node_modules` directory - to achieve this, just run `npm dedupe` (or the yarn equivalent). + +The same rule applies to this error: `node_modules/type-graphql/node_modules/@types/graphql/type/schema").GraphQLSchema' is not assignable to type 'import("node_modules/@types/graphql/type/schema").GraphQLSchema'`. +In this case we repeat the same checks but for the `@types/graphql` module in our dependencies. + +## Types + +### Is `@InputType()` different from `@ArgsType()`? + +Of course! +`@InputType` will generate a real `GraphQLInputType` type and should be used when we need a nested object in the args: + +```graphql +updateItem(data: UpdateItemInput!): Item! +``` + +`@ArgsType` is virtual and it will be flattened in schema: + +```graphql +updateItem(id: Int!, userId: Int!): Item! +``` + +### When should I use the `() => [ItemType]` syntax? + +We should use the `[ItemType]` syntax any time the field type or the return type is an array from a query or mutation. + +Even though technically the array notation can be omitted (when the base type is not `Promise`) and only provide the type of array item (e.g. `@Field(() => ItemType) field: ItemType[]`) - it's better to be consistent with other annotations by explicitly defining the type. + +### How can I define a tuple? + +Unfortunately, [GraphQL spec doesn't support tuples](https://github.com/graphql/graphql-spec/issues/423), so you can't just use `data: [Int, Float]` as a GraphQL type. + +Instead, you have to create a transient object (or input) type that fits your data, e.g.: + +```graphql +type DataPoint { + x: Int + y: Float +} +``` + +and then use it in the list type as your GraphQL type: + +```graphql +data: [DataPoint] +``` + +### Situations frequently arise where InputType and ObjectType have exactly the same shape. How can I share the definitions? + +In GraphQL, input objects have a separate type in the system because object types can contain fields that express circular references or references to interfaces and unions, neither of which are appropriate for use as input arguments. +However, if there are only simple fields in the class definition, reuse the code between the InputType and the ObjectType by decorating the ObjectType class with `@InputType`. Remember to set a new name of the type in the decorator parameter: + +```ts +@ObjectType() // Name inferred as 'Person' from class name +@InputType("PersonInput") +export class Person {} +``` diff --git a/website/versioned_docs/version-2.0.0-beta.3/generic-types.md b/website/versioned_docs/version-2.0.0-beta.3/generic-types.md new file mode 100644 index 000000000..1d501be8b --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/generic-types.md @@ -0,0 +1,169 @@ +--- +title: Generic Types +id: version-2.0.0-beta.3-generic-types +original_id: generic-types +--- + +[Type Inheritance](./inheritance.md) is a great way to reduce code duplication by extracting common fields to the base class. But in some cases, the strict set of fields is not enough because we might need to declare the types of some fields in a more flexible way, like a type parameter (e.g. `items: T[]` in case of a pagination). + +Hence TypeGraphQL also has support for describing generic GraphQL types. + +## How to? + +Unfortunately, the limited reflection capabilities of TypeScript don't allow for combining decorators with standard generic classes. To achieve behavior like that of generic types, we use the same class-creator pattern like the one described in the [Resolvers Inheritance](./inheritance.md) docs. + +### Basic usage + +Start by defining a `PaginatedResponse` function that creates and returns an abstract `PaginatedResponseClass`: + +```ts +export default function PaginatedResponse() { + abstract class PaginatedResponseClass { + // ... + } + return PaginatedResponseClass; +} +``` + +To achieve generic-like behavior, the function has to be generic and take some runtime argument related to the type parameter: + +```ts +export default function PaginatedResponse(TItemClass: ClassType) { + abstract class PaginatedResponseClass { + // ... + } + return PaginatedResponseClass; +} +``` + +Then, add proper decorators to the class which might be `@ObjectType`, `@InterfaceType` or `@InputType`: + +```ts +export default function PaginatedResponse(TItemClass: ClassType) { + @ObjectType() + abstract class PaginatedResponseClass { + // ... + } + return PaginatedResponseClass; +} +``` + +After that, add fields like in a normal class but using the generic type and parameters: + +```ts +export default function PaginatedResponse(TItemClass: ClassType) { + @ObjectType() + abstract class PaginatedResponseClass { + // Runtime argument + @Field(type => [TItemClass]) + // Generic type + items: TItem[]; + + @Field(type => Int) + total: number; + + @Field() + hasMore: boolean; + } + return PaginatedResponseClass; +} +``` + +Finally, use the generic function factory to create a dedicated type class: + +```ts +@ObjectType() +class PaginatedUserResponse extends PaginatedResponse(User) { + // Add more fields or overwrite the existing one's types + @Field(type => [String]) + otherInfo: string[]; +} +``` + +And then use it in our resolvers: + +```ts +@Resolver() +class UserResolver { + @Query() + users(): PaginatedUserResponse { + // Custom business logic, + // depending on underlying data source and libraries + return { + items, + total, + hasMore, + otherInfo, + }; + } +} +``` + +### Complex generic type values + +When we need to provide something different than a class (object type) for the field type, we need to enhance the parameter type signature and provide the needed types. + +Basically, the parameter that the `PaginatedResponse` function accepts is the value we can provide to `@Field` decorator. +So if we want to return an array of strings as the `items` field, we need to add proper types to the function signature, like `GraphQLScalarType` or `String`: + +```ts +export default function PaginatedResponse( + itemsFieldValue: ClassType | GraphQLScalarType | String | Number | Boolean, +) { + @ObjectType() + abstract class PaginatedResponseClass { + @Field(type => [itemsFieldValue]) + items: TItemsFieldValue[]; + + // ... Other fields + } + return PaginatedResponseClass; +} +``` + +And then provide a proper runtime value (like `String`) while creating a proper subtype of generic `PaginatedResponse` object type: + +```ts +@ObjectType() +class PaginatedStringsResponse extends PaginatedResponse(String) { + // ... +} +``` + +### Types factory + +We can also create a generic class without using the `abstract` keyword. +But with this approach, types created with this kind of factory will be registered in the schema, so this way is not recommended to extend the types for adding fields. + +To avoid generating schema errors of duplicated `PaginatedResponseClass` type names, we must provide our own unique, generated type name: + +```ts +export default function PaginatedResponse(TItemClass: ClassType) { + // Provide a unique type name used in schema + @ObjectType(`Paginated${TItemClass.name}Response`) + class PaginatedResponseClass { + // ... + } + return PaginatedResponseClass; +} +``` + +Then, we can store the generated class in a variable and in order to use it both as a runtime object and as a type, we must also create a type for this new class: + +```ts +const PaginatedUserResponse = PaginatedResponse(User); +type PaginatedUserResponse = InstanceType; + +@Resolver() +class UserResolver { + // Provide a runtime type argument to the decorator + @Query(returns => PaginatedUserResponse) + users(): PaginatedUserResponse { + // Same implementation as in the earlier code snippet + } +} +``` + +## Examples + +A more advanced usage example of the generic types feature can be found in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/generic-types). diff --git a/website/versioned_docs/version-2.0.0-beta.3/getting-started.md b/website/versioned_docs/version-2.0.0-beta.3/getting-started.md new file mode 100644 index 000000000..b2e8ab4ac --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/getting-started.md @@ -0,0 +1,190 @@ +--- +title: Getting started +id: version-2.0.0-beta.3-getting-started +original_id: getting-started +--- + +> Make sure you've completed all the steps described in the [installation instructions](./installation.md). + +To explore all of the powerful capabilities of TypeGraphQL, we will create a sample GraphQL API for cooking recipes. + +Let's start with the `Recipe` type, which is the foundation of our API. + +## Types + +Our goal is to get the equivalent of this type described in SDL: + +```graphql +type Recipe { + id: ID! + title: String! + description: String + creationDate: Date! + ingredients: [String!]! +} +``` + +So we create the `Recipe` class with all its properties and types: + +```ts +class Recipe { + id: string; + title: string; + description?: string; + creationDate: Date; + ingredients: string[]; +} +``` + +Then we decorate the class and its properties with decorators: + +```ts +@ObjectType() +class Recipe { + @Field(type => ID) + id: string; + + @Field() + title: string; + + @Field({ nullable: true }) + description?: string; + + @Field() + creationDate: Date; + + @Field(type => [String]) + ingredients: string[]; +} +``` + +The detailed rules of when to use `nullable`, `array` and others are described in the [fields and types docs](./types-and-fields.md). + +## Resolvers + +After that we want to create typical crud queries and mutations. To do so, we create the resolver (controller) class that will have injected the `RecipeService` in the constructor: + +```ts +@Resolver(Recipe) +class RecipeResolver { + constructor(private recipeService: RecipeService) {} + + @Query(returns => Recipe) + async recipe(@Arg("id") id: string) { + const recipe = await this.recipeService.findById(id); + if (recipe === undefined) { + throw new RecipeNotFoundError(id); + } + return recipe; + } + + @Query(returns => [Recipe]) + recipes(@Args() { skip, take }: RecipesArgs) { + return this.recipeService.findAll({ skip, take }); + } + + @Mutation(returns => Recipe) + @Authorized() + addRecipe( + @Arg("newRecipeData") newRecipeData: NewRecipeInput, + @Ctx("user") user: User, + ): Promise { + return this.recipeService.addNew({ data: newRecipeData, user }); + } + + @Mutation(returns => Boolean) + @Authorized(Roles.Admin) + async removeRecipe(@Arg("id") id: string) { + try { + await this.recipeService.removeById(id); + return true; + } catch { + return false; + } + } +} +``` + +We use the `@Authorized()` decorator to restrict access to authorized users only or the users that fulfil the roles requirements. +The detailed rules for when and why we declare `returns => Recipe` functions and others are described in [resolvers docs](./resolvers.md). + +## Inputs and Arguments + +Ok, but what are `NewRecipeInput` and `RecipesArgs`? They are, of course, classes: + +```ts +@InputType() +class NewRecipeInput { + @Field() + @MaxLength(30) + title: string; + + @Field({ nullable: true }) + @Length(30, 255) + description?: string; + + @Field(type => [String]) + @ArrayMaxSize(30) + ingredients: string[]; +} + +@ArgsType() +class RecipesArgs { + @Field(type => Int) + @Min(0) + skip: number = 0; + + @Field(type => Int) + @Min(1) + @Max(50) + take: number = 25; +} +``` + +`@Length`, `@Min` and `@ArrayMaxSize` are decorators from [`class-validator`](https://github.com/typestack/class-validator) that automatically perform field validation in TypeGraphQL. + +## Building schema + +The last step that needs to be done is to actually build the schema from the TypeGraphQL definition. We use the `buildSchema` function for this: + +```ts +const schema = await buildSchema({ + resolvers: [RecipeResolver], +}); + +// ... Server +``` + +Et voilΓ ! Now we have fully functional GraphQL schema! +If we print it, this is how it would look: + +```graphql +type Recipe { + id: ID! + title: String! + description: String + creationDate: Date! + ingredients: [String!]! +} +input NewRecipeInput { + title: String! + description: String + ingredients: [String!]! +} +type Query { + recipe(id: ID!): Recipe + recipes(skip: Int = 0, take: Int = 25): [Recipe!]! +} +type Mutation { + addRecipe(newRecipeData: NewRecipeInput!): Recipe! + removeRecipe(id: ID!): Boolean! +} +``` + +## Want more? + +That was only the tip of the iceberg - a very simple example with basic GraphQL types. Do you use interfaces, enums, unions and custom scalars? That's great because TypeGraphQL fully supports them too! There are also more advanced concepts like the authorization checker, inheritance support and field resolvers. + +A lot of these topics are covered in [Ben Awad](https://github.com/benawad)'s [TypeGraphQL video series](https://www.youtube.com/playlist?list=PLN3n1USn4xlma1bBu3Tloe4NyYn9Ko8Gs) on YouTube. + +For more complicated cases, go to the [Examples section](./examples.md) where you can discover e.g. how well TypeGraphQL integrates with TypeORM. diff --git a/website/versioned_docs/version-2.0.0-beta.3/inheritance.md b/website/versioned_docs/version-2.0.0-beta.3/inheritance.md new file mode 100644 index 000000000..48dbe6721 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/inheritance.md @@ -0,0 +1,145 @@ +--- +title: Inheritance +id: version-2.0.0-beta.3-inheritance +original_id: inheritance +--- + +The main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes. + +In object-oriented programming it is common to compose classes using inheritance. Hence, TypeGraphQL supports composing type definitions by extending classes. + +## Types inheritance + +One of the most known principles of software development is DRY - Don't Repeat Yourself - which is about avoiding code redundancy. + +While creating a GraphQL API, it's a common pattern to have pagination args in resolvers, like `skip` and `take`. So instead of repeating ourselves, we declare it once: + +```ts +@ArgsType() +class PaginationArgs { + @Field(type => Int) + skip: number = 0; + + @Field(type => Int) + take: number = 25; +} +``` + +and then reuse it everywhere: + +```ts +@ArgsType() +class GetTodosArgs extends PaginationArgs { + @Field() + onlyCompleted: boolean = false; +} +``` + +This technique also works with input type classes, as well as with object type classes: + +```ts +@ObjectType() +class Person { + @Field() + age: number; +} + +@ObjectType() +class Student extends Person { + @Field() + universityName: string; +} +``` + +Note that both the subclass and the parent class must be decorated with the same type of decorator, like `@ObjectType()` in the example `Person -> Student` above. Mixing decorator types across parent and child classes is prohibited and might result in a schema building error, e.g. we can't decorate the subclass with `@ObjectType()` and the parent with `@InputType()`. + +## Resolver Inheritance + +A special kind of inheritance in TypeGraphQL is resolver class inheritance. This pattern allows us e.g. to create a base CRUD resolver class for our resource/entity, so we don't have to repeat common boilerplate code. + +Since we need to generate unique query/mutation names, we have to create a factory function for our base class: + +```ts +function createBaseResolver() { + abstract class BaseResolver {} + + return BaseResolver; +} +``` + +Be aware that with some `tsconfig.json` settings (like `declarations: true`) we might receive a `[ts] Return type of exported function has or is using private name 'BaseResolver'` error - in this case we might need to use `any` as the return type or create a separate class/interface describing the class methods and properties. + +This factory should take a parameter that we can use to generate the query/mutation names, as well as the type that we would return from the resolvers: + +```ts +function createBaseResolver(suffix: string, objectTypeCls: T) { + abstract class BaseResolver {} + + return BaseResolver; +} +``` + +It's very important to mark the `BaseResolver` class using the `@Resolver` decorator: + +```ts +function createBaseResolver(suffix: string, objectTypeCls: T) { + @Resolver() + abstract class BaseResolver {} + + return BaseResolver; +} +``` + +We can then implement the resolver methods as usual. The only difference is that we can use the `name` decorator option for `@Query`, `@Mutation` and `@Subscription` decorators to overwrite the name that will be emitted in schema: + +```ts +function createBaseResolver(suffix: string, objectTypeCls: T) { + @Resolver() + abstract class BaseResolver { + protected items: T[] = []; + + @Query(type => [objectTypeCls], { name: `getAll${suffix}` }) + async getAll(@Arg("first", type => Int) first: number): Promise { + return this.items.slice(0, first); + } + } + + return BaseResolver; +} +``` + +Now we can create a specific resolver class that will extend the base resolver class: + +```ts +const PersonBaseResolver = createBaseResolver("person", Person); + +@Resolver(of => Person) +export class PersonResolver extends PersonBaseResolver { + // ... +} +``` + +We can also add specific queries and mutations in our resolver class, as always: + +```ts +const PersonBaseResolver = createBaseResolver("person", Person); + +@Resolver(of => Person) +export class PersonResolver extends PersonBaseResolver { + @Mutation() + addPerson(@Arg("input") personInput: PersonInput): Person { + this.items.push(personInput); + return personInput; + } +} +``` + +And that's it! We just need to normally register `PersonResolver` in `buildSchema` and the extended resolver will work correctly. + +We must be aware that if we want to overwrite the query/mutation/subscription from the parent resolver class, we need to generate the same schema name (using the `name` decorator option or the class method name). It will overwrite the implementation along with the GraphQL args and return types. If we only provide a different implementation of the inherited method like `getOne`, it won't work. + +## Examples + +More advanced usage examples of type inheritance (and interfaces) can be found in [the example folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/interfaces-inheritance). + +For a more advanced resolver inheritance example, please go to [this example folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/resolvers-inheritance). diff --git a/website/versioned_docs/version-2.0.0-beta.3/installation.md b/website/versioned_docs/version-2.0.0-beta.3/installation.md new file mode 100644 index 000000000..3d2ef08a9 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/installation.md @@ -0,0 +1,63 @@ +--- +title: Installation +id: version-2.0.0-beta.3-installation +original_id: installation +--- + +Before getting started with TypeGraphQL we need to install some additional dependencies and properly configure the TypeScript configuration for our project. + +> #### Prerequisites +> +> Before we begin, we must make sure our development environment includes Node.js and npm. + +## Packages installation + +First, we have to install the main package, as well as [`graphql-js`](https://github.com/graphql/graphql-js) and [`graphql-scalars`](https://github.com/urigo/graphql-scalars) which are peer dependencies of TypeGraphQL: + +```sh +npm install graphql graphql-scalars type-graphql +``` + +Also, the `reflect-metadata` shim is required to make the type reflection work: + +```sh +npm install reflect-metadata +``` + +We must ensure that it is imported at the top of our entry file (before we use/import `type-graphql` or our resolvers): + +```ts +import "reflect-metadata"; +``` + +## TypeScript configuration + +It's important to set these options in the `tsconfig.json` file of our project: + +```json +{ + "emitDecoratorMetadata": true, + "experimentalDecorators": true +} +``` + +`TypeGraphQL` is designed to work with Node.js LTS and the latest stable releases. It uses features from ES2021 so we should set our `tsconfig.json` file appropriately: + +```js +{ + "target": "es2021" // Or newer if Node.js version supports it +} +``` + +All in all, the minimal `tsconfig.json` file example looks like this: + +```json +{ + "compilerOptions": { + "target": "es2021", + "module": "commonjs", + "experimentalDecorators": true, + "emitDecoratorMetadata": true + } +} +``` diff --git a/website/versioned_docs/version-2.0.0-beta.3/interfaces.md b/website/versioned_docs/version-2.0.0-beta.3/interfaces.md new file mode 100644 index 000000000..c7e5b6b63 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/interfaces.md @@ -0,0 +1,258 @@ +--- +title: Interfaces +id: version-2.0.0-beta.3-interfaces +original_id: interfaces +--- + +The main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes. + +In object-oriented programming it is common to create interfaces which describe the contract that classes implementing them must adhere to. Hence, TypeGraphQL supports defining GraphQL interfaces. + +Read more about the GraphQL Interface Type in the [official GraphQL docs](https://graphql.org/learn/schema/#interfaces). + +## Abstract classes + +TypeScript has first class support for interfaces. Unfortunately, they only exist at compile-time, so we can't use them to build GraphQL schema at runtime by using decorators. + +Luckily, we can use an abstract class for this purpose. It behaves almost like an interface as it can't be instantiated but it can be implemented by another class. The only difference is that it just won't prevent developers from implementing a method or initializing a field. So, as long as we treat the abstract class like an interface, we can safely use it. + +## Defining interface type + +How do we create a GraphQL interface definition? We create an abstract class and decorate it with the `@InterfaceType()` decorator. The rest is exactly the same as with object types: we use the `@Field` decorator to declare the shape of the type: + +```ts +@InterfaceType() +abstract class IPerson { + @Field(type => ID) + id: string; + + @Field() + name: string; + + @Field(type => Int) + age: number; +} +``` + +We can then use this interface type class like an interface in the object type class definition: + +```ts +@ObjectType({ implements: IPerson }) +class Person implements IPerson { + id: string; + name: string; + age: number; +} +``` + +The only difference is that we have to let TypeGraphQL know that this `ObjectType` is implementing the `InterfaceType`. We do this by passing the param `({ implements: IPerson })` to the decorator. If we implement multiple interfaces, we pass an array of interfaces like so: `({ implements: [IPerson, IAnimal, IMachine] })`. + +It is also allowed to omit the decorators since the GraphQL types will be copied from the interface definition - this way we won't have to maintain two definitions and solely rely on TypeScript type checking for correct interface implementation. + +We can also extend the base interface type abstract class as well because all the fields are inherited and emitted in schema: + +```ts +@ObjectType({ implements: IPerson }) +class Person extends IPerson { + @Field() + hasKids: boolean; +} +``` + +## Implementing other interfaces + +Since `graphql-js` version `15.0`, it's also possible for interface type to [implement other interface types](https://github.com/graphql/graphql-js/pull/2084). + +To accomplish this, we can just use the same syntax that we utilize for object types - the `implements` decorator option: + +```ts +@InterfaceType() +class Node { + @Field(type => ID) + id: string; +} + +@InterfaceType({ implements: Node }) +class Person extends Node { + @Field() + name: string; + + @Field(type => Int) + age: number; +} +``` + +Also, when we implement the interface that already implements other interface, there's no need to put them all in `implements` array in `@ObjectType` decorator option - only the closest one in the inheritance chain is required, e.g.: + +```ts +@ObjectType({ implements: [Person] }) +class Student extends Person { + @Field() + universityName: string; +} +``` + +This example produces following representation in GraphQL SDL: + +```graphql +interface Node { + id: ID! +} + +interface Person implements Node { + id: ID! + name: String! + age: Int! +} + +type Student implements Node & Person { + id: ID! + name: String! + age: Int! + universityName: String! +} +``` + +## Resolvers and arguments + +What's more, we can define resolvers for the interface fields, using the same syntax we would use when defining one for our object type: + +```ts +@InterfaceType() +abstract class IPerson { + @Field() + firstName: string; + + @Field() + lastName: string; + + @Field() + fullName(): string { + return `${this.firstName} ${this.lastName}`; + } +} +``` + +They're inherited by all the object types that implements this interface type but does not provide their own resolver implementation for those fields. + +Additionally, if we want to declare that the interface accepts some arguments, e.g.: + +```graphql +interface IPerson { + avatar(size: Int!): String! +} +``` + +We can just use `@Arg` or `@Args` decorators as usual: + +```ts +@InterfaceType() +abstract class IPerson { + @Field() + avatar(@Arg("size") size: number): string { + return `http://i.pravatar.cc/${size}`; + } +} +``` + +Unfortunately, TypeScript doesn't allow using decorators on abstract methods. +So if we don't want to provide implementation for that field resolver, only to enforce some signature (args and return type), we have to throw an error inside the body: + +```ts +@InterfaceType() +abstract class IPerson { + @Field() + avatar(@Arg("size") size: number): string { + throw new Error("Method not implemented!"); + } +} +``` + +And then we need to extend the interface class and override the method by providing its body - it is required for all object types that implements that interface type: + +```ts +@ObjectType({ implements: IPerson }) +class Person extends IPerson { + avatar(size: number): string { + return `http://i.pravatar.cc/${size}`; + } +} +``` + +In order to extend the signature by providing additional arguments (like `format`), we need to redeclare the whole field signature: + +```ts +@ObjectType({ implements: IPerson }) +class Person implements IPerson { + @Field() + avatar(@Arg("size") size: number, @Arg("format") format: string): string { + return `http://i.pravatar.cc/${size}.${format}`; + } +} +``` + +Resolvers for interface type fields can be also defined on resolvers classes level, by using the `@FieldResolver` decorator: + +```ts +@Resolver(of => IPerson) +class IPersonResolver { + @FieldResolver() + avatar(@Root() person: IPerson, @Arg("size") size: number): string { + return `http://typegraphql.com/${person.id}/${size}`; + } +} +``` + +## Registering in schema + +By default, if the interface type is explicitly used in schema definition (used as a return type of a query/mutation or as some field type), all object types that implement that interface will be emitted in schema, so we don't need to do anything. + +However, in some cases like the `Node` interface that is used in Relay-based systems, this behavior might be not intended when exposing multiple, separates schemas (like a public and the private ones). + +In this situation, we can provide an `{ autoRegisterImplementations: false }` option to the `@InterfaceType` decorator to prevent emitting all this object types in the schema: + +```ts +@InterfaceType({ autoRegisterImplementations: false }) +abstract class Node { + @Field(type => ID) + id: string; +} +``` + +Then we need to add all the object types (that implement this interface type and which we want to expose in selected schema) to the `orphanedTypes` array option in `buildSchema`: + +```ts +const schema = await buildSchema({ + resolvers, + // Provide orphaned object types + orphanedTypes: [Person, Animal, Recipe], +}); +``` + +Be aware that if the object type class is explicitly used as the GraphQL type (like `Recipe` type as the return type of `addRecipe` mutation), it will be emitted regardless the `orphanedTypes` setting. + +## Resolving Type + +Be aware that when our object type is implementing a GraphQL interface type, **we have to return an instance of the type class** in our resolvers. Otherwise, `graphql-js` will not be able to detect the underlying GraphQL type correctly. + +We can also provide our own `resolveType` function implementation to the `@InterfaceType` options. This way we can return plain objects in resolvers and then determine the returned object type by checking the shape of the data object, the same ways [like in unions](./unions.md), e.g.: + +```ts +@InterfaceType({ + resolveType: value => { + if ("grades" in value) { + return "Student"; // Schema name of type string + } + return Person; // Or object type class + }, +}) +abstract class IPerson { + // ... +} +``` + +However in case of interfaces, it might be a little bit more tricky than with unions, as we might not remember all the object types that implements this particular interface. + +## Examples + +For more advanced usage examples of interfaces (and type inheritance), e.g. with query returning an interface type, go to [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/interfaces-inheritance). diff --git a/website/versioned_docs/version-2.0.0-beta.3/introduction.md b/website/versioned_docs/version-2.0.0-beta.3/introduction.md new file mode 100644 index 000000000..26cd5ed09 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/introduction.md @@ -0,0 +1,59 @@ +--- +title: Introduction +sidebar_label: What & Why +id: version-2.0.0-beta.3-introduction +original_id: introduction +--- + +We all love GraphQL! It's really great and solves many problems that we have with REST APIs, such as overfetching and underfetching. But developing a GraphQL API in Node.js with TypeScript is sometimes a bit of a pain. + +## What? + +**TypeGraphQL** is a library that makes this process enjoyable by defining the schema using only classes and a bit of decorator magic. +Example object type: + +```ts +@ObjectType() +class Recipe { + @Field() + title: string; + + @Field(type => [Rate]) + ratings: Rate[]; + + @Field({ nullable: true }) + averageRating?: number; +} +``` + +It also has a set of useful features, like validation, authorization and dependency injection, which helps develop GraphQL APIs quickly & easily! + +## Why? + +As mentioned, developing a GraphQL API in Node.js with TypeScript is sometimes a bit of a pain. +Why? Let's take a look at the steps we usually have to take. + +First, we create all the schema types in SDL. We also create our data models using [ORM classes](https://github.com/typeorm/typeorm), which represent our database entities. Then we start to write resolvers for our queries, mutations and fields. This forces us, however, to begin with creating TypeScript interfaces for all arguments and inputs and/or object types. After that, we can actually implement the resolvers, using weird generic signatures, e.g.: + +```ts +export const getRecipesResolver: GraphQLFieldResolver = async ( + _, + args, + ctx, +) => { + // Common tasks repeatable for almost every resolver + const auth = Container.get(AuthService); + if (!auth.check(ctx.user)) { + throw new NotAuthorizedError(); + } + await joi.validate(getRecipesSchema, args); + const repository = TypeORM.getRepository(Recipe); + + // Business logic, e.g.: + return repository.find({ skip: args.offset, take: args.limit }); +}; +``` + +The biggest problem is code redundancy which makes it difficult to keep things in sync. To add a new field to our entity, we have to jump through all the files: modify the entity class, then modify the schema, and finally update the interface. The same goes with inputs or arguments: it's easy to forget to update one of them or make a mistake with a type. Also, what if we've made a typo in a field name? The rename feature (F2) won't work correctly. + +**TypeGraphQL** comes to address these issues, based on experience from a few years of developing GraphQL APIs in TypeScript. The main idea is to have only one source of truth by defining the schema using classes and a bit of decorator help. Additional features like dependency injection, validation and auth guards help with common tasks that would normally have to be handled by ourselves. diff --git a/website/versioned_docs/version-2.0.0-beta.3/middlewares.md b/website/versioned_docs/version-2.0.0-beta.3/middlewares.md new file mode 100644 index 000000000..5dc20c1b2 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/middlewares.md @@ -0,0 +1,189 @@ +--- +title: Middleware and guards +id: version-2.0.0-beta.3-middlewares +original_id: middlewares +--- + +Middleware are pieces of reusable code that can be easily attached to resolvers and fields. By using middleware we can extract the commonly used code from our resolvers and then declaratively attach it using a decorator or even registering it globally. + +## Creating Middleware + +### What is Middleware? + +Middleware is a very powerful but somewhat complicated feature. Basically, middleware is a function that takes 2 arguments: + +- resolver data - the same as resolvers (`root`, `args`, `context`, `info`) +- the `next` function - used to control the execution of the next middleware and the resolver to which it is attached + +We may be familiar with how middleware works in [`express.js`](https://expressjs.com/en/guide/writing-middleware.html) but TypeGraphQL middleware is inspired by [`koa.js`](http://koajs.com/#application). The difference is that the `next` function returns a promise of the value of subsequent middleware and resolver execution from the stack. + +This makes it easy to perform actions before or after resolver execution. So things like measuring execution time are simple to implement: + +```ts +export const ResolveTime: MiddlewareFn = async ({ info }, next) => { + const start = Date.now(); + await next(); + const resolveTime = Date.now() - start; + console.log(`${info.parentType.name}.${info.fieldName} [${resolveTime} ms]`); +}; +``` + +### Intercepting the execution result + +Middleware also has the ability to intercept the result of a resolver's execution. It's not only able to e.g. create a log but also replace the result with a new value: + +```ts +export const CompetitorInterceptor: MiddlewareFn = async (_, next) => { + const result = await next(); + if (result === "typegql") { + return "type-graphql"; + } + return result; +}; +``` + +It might not seem very useful from the perspective of this library's users but this feature was mainly introduced for plugin systems and 3rd-party library integration. Thanks to this, it's possible to e.g. wrap the returned object with a lazy-relation wrapper that automatically fetches relations from a database on demand under the hood. + +### Simple Middleware + +If we only want to do something before an action, like log the access to the resolver, we can just place the `return next()` statement at the end of our middleware: + +```ts +const LogAccess: MiddlewareFn = ({ context, info }, next) => { + const username: string = context.username || "guest"; + console.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`); + return next(); +}; +``` + +### Guards + +Middleware can also break the middleware stack by not calling the `next` function. This way, the result returned from the middleware will be used instead of calling the resolver and returning it's result. + +We can also throw an error in the middleware if the execution must be terminated and an error returned to the user, e.g. when resolver arguments are incorrect. + +This way we can create a guard that blocks access to the resolver and prevents execution or any data return. + +```ts +export const CompetitorDetector: MiddlewareFn = async ({ args }, next) => { + if (args.frameworkName === "type-graphql") { + return "TypeGraphQL"; + } + if (args.frameworkName === "typegql") { + throw new Error("Competitive framework detected!"); + } + return next(); +}; +``` + +### Reusable Middleware + +Sometimes middleware has to be configurable, just like we pass a `roles` array to the [`@Authorized()` decorator](./authorization.md). In this case, we should create a simple middleware factory - a function that takes our configuration as a parameter and returns a middleware that uses the provided value. + +```ts +export function NumberInterceptor(minValue: number): MiddlewareFn { + return async (_, next) => { + const result = await next(); + // Hide values below minValue + if (typeof result === "number" && result < minValue) { + return null; + } + return result; + }; +} +``` + +Remember to call this middleware with an argument, e.g. `NumberInterceptor(3.0)`, when attaching it to a resolver! + +### Error Interceptors + +Middleware can also catch errors that were thrown during execution. This way, they can easily be logged and even filtered for info that can't be returned to the user: + +```ts +export const ErrorInterceptor: MiddlewareFn = async ({ context, info }, next) => { + try { + return await next(); + } catch (err) { + // Write error to file log + fileLog.write(err, context, info); + + // Hide errors from db like printing sql query + if (someCondition(err)) { + throw new Error("Unknown error occurred!"); + } + + // Rethrow the error + throw err; + } +}; +``` + +### Class-based Middleware + +Sometimes our middleware logic can be a bit complicated - it may communicate with a database, write logs to file, etc., so we might want to test it. In that case we create class middleware that is able to benefit from [dependency injection](./dependency-injection.md) and easily mock a file logger or a database repository. + +To accomplish this, we implement a `MiddlewareInterface`. Our class must have the `use` method that conforms with the `MiddlewareFn` signature. Below we can see how the previously defined `LogAccess` middleware looks after the transformation: + +```ts +export class LogAccess implements MiddlewareInterface { + constructor(private readonly logger: Logger) {} + + async use({ context, info }: ResolverData, next: NextFn) { + const username: string = context.username || "guest"; + this.logger.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`); + return next(); + } +} +``` + +## How to use + +### Attaching Middleware + +To attach middleware to a resolver, place the `@UseMiddleware()` decorator above the field or resolver declaration. It accepts an array of middleware that will be called in the provided order. We can also pass them without an array as it supports [rest parameters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters): + +```ts +@Resolver() +export class RecipeResolver { + @Query() + @UseMiddleware(ResolveTime, LogAccess) + randomValue(): number { + return Math.random(); + } +} +``` + +We can also attach the middleware to the `ObjectType` fields, the same way as with the [`@Authorized()` decorator](./authorization.md). + +```ts +@ObjectType() +export class Recipe { + @Field() + title: string; + + @Field(type => [Int]) + @UseMiddleware(LogAccess) + ratings: number[]; +} +``` + +### Global Middleware + +However, for common middleware like measuring resolve time or catching errors, it might be annoying to place a `@UseMiddleware(ResolveTime)` decorator on every field/resolver. + +Hence, in TypeGraphQL we can also register a global middleware that will be called for each query, mutation, subscription and field resolver. For this, we use the `globalMiddlewares` property of the `buildSchema` configuration object: + +```ts +const schema = await buildSchema({ + resolvers: [RecipeResolver], + globalMiddlewares: [ErrorInterceptor, ResolveTime], +}); +``` + +### Custom Decorators + +If we want to use middlewares with a more descriptive and declarative API, we can also create a custom method decorators. See how to do this in [custom decorators docs](./custom-decorators.md#method-decorators). + +## Example + +See how different kinds of middlewares work in the [middlewares and custom decorators example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/middlewares-custom-decorators). diff --git a/website/versioned_docs/version-2.0.0-beta.3/nestjs.md b/website/versioned_docs/version-2.0.0-beta.3/nestjs.md new file mode 100644 index 000000000..eff10ba65 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/nestjs.md @@ -0,0 +1,49 @@ +--- +title: NestJS Integration +sidebar_label: NestJS +id: version-2.0.0-beta.3-nestjs +original_id: nestjs +--- + +TypeGraphQL provides some basic integration with NestJS by the [`typegraphql-nestjs` package](https://www.npmjs.com/package/typegraphql-nestjs). + +It allows to use TypeGraphQL features while integrating with NestJS modules system and its dependency injector. + +## Overview + +The usage is similar to the official `@nestjs/graphql` package. +First you need to register your resolver classes in `providers` of the `@Module` : + +```ts +@Module({ + providers: [RecipeResolver, RecipeService], +}) +export default class RecipeModule {} +``` + +Then you need to register the TypeGraphQL module in your root module - you can pass there all standard `buildSchema` options: + +```ts +@Module({ + imports: [ + TypeGraphQLModule.forRoot({ + emitSchemaFile: true, + authChecker, + context: ({ req }) => ({ currentUser: req.user }), + }), + RecipeModule, + ], +}) +export default class AppModule {} +``` + +And your `AppModule` is ready to use like with a standard NestJS approach. + +### Caveats + +For now, this basic integration doesn't support other NestJS features like guards, interceptors, filters and pipes. +To achieve the same goals, you can use standard TypeGraphQL equivalents - middlewares, custom decorators, built-in authorization and validation. + +## Documentation and examples + +You can find some examples and more detailed info about the installation and the usage [in the separate GitHub repository](https://github.com/MichalLytek/typegraphql-nestjs). diff --git a/website/versioned_docs/version-2.0.0-beta.3/performance.md b/website/versioned_docs/version-2.0.0-beta.3/performance.md new file mode 100644 index 000000000..8bfa9e8da --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/performance.md @@ -0,0 +1,83 @@ +--- +title: Performance +id: version-2.0.0-beta.3-performance +original_id: performance +--- + +**TypeGraphQL** is basically an abstraction layer built on top of the reference GraphQL implementation for Javascript - [`graphql-js`](https://github.com/graphql/graphql-js). It not only allows for building a GraphQL schema using classes and decorators but also gives a set of tools that focus on the developer experience and allows for making common tasks easily - authorization, validation, custom middlewares and others. + +While this enable easy and convenient development, it's sometimes a tradeoff in a performance. + +## Benchmarks + +To measure the overhead of the abstraction, a few demo examples were made to compare the usage of TypeGraphQL against the implementations using "bare metal" - raw `graphql-js` library. The benchmarks are located in a [folder on the GitHub repo](../benchmarks). + +The most demanding cases like returning an array of 25 000 nested objects showed that in some cases it might be about 5 times slower. + +| | 25 000 array items | Deeply nested object | +| -------------------- | :----------------: | :------------------: | +| Standard TypeGraphQL | 1253.28 ms | 45.57 ΞΌs | +| `graphql-js` | 265.52 ms | 24.22 ΞΌs | + +In real apps (e.g. with complex database queries) it's usually a much lower factor but still not negligible. That's why TypeGraphQL has some built-in performance optimization options. + +## Optimizations + +Promises in JS have a quite big performance overhead. In the same example of returning an array with 25 000 items, if we change the Object Type field resolvers to an asynchronous one that return a promise, the execution slows down by a half even in "raw" `graphql-js`. + +| `graphql-js` | 25 000 array items | +| --------------- | :----------------: | +| sync resolvers | 265.52 ms | +| async resolvers | 512.61 ms | + +TypeGraphQL tries to avoid the async execution path when it's possible, e.g. if the query/mutation/field resolver doesn't use the auth feature, doesn't use args (or has args validation disabled) and if doesn't return a promise. So if you find a bottleneck in your app, try to investigate your resolvers, disable not used features and maybe remove some unnecessary async/await usage. + +Also, using middlewares implicitly turns on the async execution path (for global middlewares the middlewares stack is created even for every implicit field resolver!), so be careful when using this feature if you care about the performance very much (and maybe then use the "simple resolvers" tweak described below). + +The whole middleware stack will be soon redesigned with a performance in mind and with a new API that will also allow fine-grained scoping of global middlewares. Stay tuned! + +## Further performance tweaks + +When we have a query that returns a huge amount of JSON-like data and we don't need any field-level access control or other custom middlewares, we can turn off the whole authorization and middlewares stack for selected field resolver using a `{ simple: true }` decorator option, e.g.: + +```ts +@ObjectType() +class SampleObject { + @Field() + sampleField: string; + + @Field({ simple: true }) + publicFrequentlyQueriedField: SomeType; +} +``` + +Moreover, we can also apply this behavior for all the fields of the object type by using a `{ simpleResolvers: true }` decorator option, e.g.: + +```ts +@ObjectType({ simpleResolvers: true }) +class Post { + @Field() + title: string; + + @Field() + createdAt: Date; + + @Field() + isPublished: boolean; +} +``` + +This simple trick can speed up the execution up to 76%! The benchmarks show that using simple resolvers allows for as fast execution as with bare `graphql-js` - the measured overhead is only about ~13%, which is a much more reasonable value than 500%. Below you can see [the benchmarks results](../benchmarks): + +| | 25 000 array items | +| ------------------------------------------------------------------------ | :----------------: | +| `graphql-js` | 265.52 ms | +| Standard TypeGraphQL | 310.36 ms | +| TypeGraphQL with a global middleware | 1253.28 ms | +| **TypeGraphQL with "simpleResolvers" applied (and a global middleware)** | **299.61 ms** | + +> This optimization **is not turned on by default** mostly because of the global middlewares and authorization feature. + +By using "simple resolvers" we are turning them off, so we have to be aware of the consequences - `@Authorized` guard on fields won't work for that fields so they will be publicly available, as well as global middlewares won't be executed for that fields, so we might lost, for example, performance metrics or access logs. + +That's why we should **be really careful with using this tweak**. The rule of thumb is to use "simple resolvers" only when it's really needed, like returning huge array of nested objects. diff --git a/website/versioned_docs/version-2.0.0-beta.3/prisma.md b/website/versioned_docs/version-2.0.0-beta.3/prisma.md new file mode 100644 index 000000000..cbe1f0ea3 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/prisma.md @@ -0,0 +1,54 @@ +--- +title: Prisma Integration +sidebar_label: Prisma +id: version-2.0.0-beta.3-prisma +original_id: prisma +--- + +TypeGraphQL provides an integration with Prisma by the [`typegraphql-prisma` package](https://www.npmjs.com/package/typegraphql-prisma). + +It generates the type classes and CRUD resolvers based on the Prisma schema, so we can execute complex queries or mutations that corresponds to the Prisma actions, without having to write any code for that. + +## Overview + +To make use of the prisma integration, first we need to add a new generator to the `schema.prisma` file: + +```sh +generator typegraphql { + provider = "typegraphql-prisma" +} +``` + +Then, after running `prisma generate` we can import the generated resolvers classes and use them to build our schema: + +```ts +import { resolvers } from "@generated/type-graphql"; + +const schema = await buildSchema({ + resolvers, + validate: false, +}); +``` + +So we will be able to execute a complex query, that talks with the real database, in just a few minutes! + +```graphql +query GetSomeUsers { + users(where: { email: { contains: "prisma" } }, orderBy: { name: desc }) { + id + name + email + posts(take: 10, orderBy: { updatedAt: desc }) { + published + title + content + } + } +} +``` + +## Documentation and examples + +To read about all the `typegraphql-prisma` features, like exposing selected Prisma actions or changing exposed model type name, as well as how to write a custom query or how to add some fields to model type, please check the docs [on the dedicated website](https://prisma.typegraphql.com). + +There also can be found the links to some examples and more detailed info about the installation and the configuration. diff --git a/website/versioned_docs/version-2.0.0-beta.3/resolvers.md b/website/versioned_docs/version-2.0.0-beta.3/resolvers.md new file mode 100644 index 000000000..dab338abc --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/resolvers.md @@ -0,0 +1,352 @@ +--- +title: Resolvers +id: version-2.0.0-beta.3-resolvers +original_id: resolvers +--- + +Besides [declaring GraphQL's object types](./types-and-fields.md), TypeGraphQL allows us to easily create queries, mutations and field resolvers - like normal class methods, similar to REST controllers in frameworks like Java `Spring`, .NET `Web API` or TypeScript [`routing-controllers`](https://github.com/typestack/routing-controllers). + +## Queries and Mutations + +### Resolver classes + +First we create the resolver class and annotate it with the `@Resolver()` decorator. This class will behave like a controller from classic REST frameworks: + +```ts +@Resolver() +class RecipeResolver {} +``` + +We can use a DI framework (as described in the [dependency injection docs](./dependency-injection.md)) to inject class dependencies (like services or repositories) or to store data inside the resolver class - it's guaranteed to be a single instance per app. + +```ts +@Resolver() +class RecipeResolver { + private recipesCollection: Recipe[] = []; +} +``` + +Then we can create class methods which will handle queries and mutations. For example, let's add the `recipes` query to return a collection of all recipes: + +```ts +@Resolver() +class RecipeResolver { + private recipesCollection: Recipe[] = []; + + async recipes() { + // Fake async + return await this.recipesCollection; + } +} +``` + +We also need to do two things. +The first is to add the `@Query` decorator, which marks the class method as a GraphQL query. +The second is to provide the return type. Since the method is async, the reflection metadata system shows the return type as a `Promise`, so we have to add the decorator's parameter as `returns => [Recipe]` to declare it resolves to an array of `Recipe` object types. + +```ts +@Resolver() +class RecipeResolver { + private recipesCollection: Recipe[] = []; + + @Query(returns => [Recipe]) + async recipes() { + return await this.recipesCollection; + } +} +``` + +### Arguments + +Usually, queries have some arguments - it might be the id of a resource, a search phrase or pagination settings. TypeGraphQL allows you to define arguments in two ways. + +First is the inline method using the `@Arg()` decorator. The drawback is the need to repeating the argument name (due to a limitation of the reflection system) in the decorator parameter. As we can see below, we can also pass a `defaultValue` option that will be reflected in the GraphQL schema. + +```ts +@Resolver() +class RecipeResolver { + // ... + @Query(returns => [Recipe]) + async recipes( + @Arg("servings", { defaultValue: 2 }) servings: number, + @Arg("title", { nullable: true }) title?: string, + ): Promise { + // ... + } +} +``` + +This works well when there are 2 - 3 args. But when you have many more, the resolver's method definitions become bloated. In this case we can use a class definition to describe the arguments. It looks like the object type class but it has the `@ArgsType()` decorator on top. + +```ts +@ArgsType() +class GetRecipesArgs { + @Field(type => Int, { nullable: true }) + skip?: number; + + @Field(type => Int, { nullable: true }) + take?: number; + + @Field({ nullable: true }) + title?: string; +} +``` + +We can define default values for optional fields in the `@Field()` decorator using the `defaultValue` option or by using a property initializer - in both cases TypeGraphQL will reflect this in the schema by setting the default value, so users will be able to omit those args while sending a query. + +> Be aware that `defaultValue` works only for input args and fields, like `@Arg`, `@ArgsType` and `@InputType`. +> Setting `defaultValue` does not affect `@ObjectType` or `@InterfaceType` fields as they are for output purposes only. + +Also, this way of declaring arguments allows you to perform validation. You can find more details about this feature in the [validation docs](./validation.md). + +We can also define helper fields and methods for our args or input classes. But be aware that **defining constructors is strictly forbidden** and we shouldn't use them there, as TypeGraphQL creates instances of args and input classes under the hood by itself. + +```ts +import { Min, Max } from "class-validator"; + +@ArgsType() +class GetRecipesArgs { + @Field(type => Int, { defaultValue: 0 }) + @Min(0) + skip: number; + + @Field(type => Int) + @Min(1) + @Max(50) + take = 25; + + @Field({ nullable: true }) + title?: string; + + // Helpers - index calculations + get startIndex(): number { + return this.skip; + } + get endIndex(): number { + return this.skip + this.take; + } +} +``` + +Then all that is left to do is use the args class as the type of the method parameter. +We can use the destructuring syntax to gain access to single arguments as variables, instead of the reference to the whole args object. + +```ts +@Resolver() +class RecipeResolver { + // ... + @Query(returns => [Recipe]) + async recipes(@Args() { title, startIndex, endIndex }: GetRecipesArgs) { + // Example implementation + let recipes = this.recipesCollection; + if (title) { + recipes = recipes.filter(recipe => recipe.title === title); + } + return recipes.slice(startIndex, endIndex); + } +} +``` + +This declaration will result in the following part of the schema in SDL: + +```graphql +type Query { + recipes(skip: Int = 0, take: Int = 25, title: String): [Recipe!] +} +``` + +### Input types + +GraphQL mutations can be similarly created: Declare the class method, use the `@Mutation` decorator, create arguments, provide a return type (if needed) etc. But for mutations we usually use `input` types, hence TypeGraphQL allows us to create inputs in the same way as [object types](./types-and-fields.md) but by using the `@InputType()` decorator: + +```ts +@InputType() +class AddRecipeInput {} +``` + +To ensure we don't accidentally change the property type we leverage the TypeScript type checking system by implementing the `Partial` type: + +```ts +@InputType() +class AddRecipeInput implements Partial {} +``` + +We then declare any input fields we need, using the `@Field()` decorator: + +```ts +@InputType({ description: "New recipe data" }) +class AddRecipeInput implements Partial { + @Field() + title: string; + + @Field({ nullable: true }) + description?: string; +} +``` + +After that we can use the `AddRecipeInput` type in our mutation. We can do this inline (using the `@Arg()` decorator) or as a field of the args class like in the query example above. + +We may also need access to the context. To achieve this we use the `@Ctx()` decorator with the optional user-defined `Context` interface: + +```ts +@Resolver() +class RecipeResolver { + // ... + @Mutation() + addRecipe(@Arg("data") newRecipeData: AddRecipeInput, @Ctx() ctx: Context): Recipe { + // Example implementation + const recipe = RecipesUtils.create(newRecipeData, ctx.user); + this.recipesCollection.push(recipe); + return recipe; + } +} +``` + +Because our method is synchronous and explicitly returns `Recipe`, we can omit the `@Mutation()` type annotation. + +This declaration will result in the following part of the schema in SDL: + +```graphql +input AddRecipeInput { + title: String! + description: String +} +``` + +```graphql +type Mutation { + addRecipe(data: AddRecipeInput!): Recipe! +} +``` + +By using parameter decorators, we can get rid of unnecessary parameters (like `root`) that bloat our method definition and have to be ignored by prefixing the parameter name with `_`. Also, we can achieve a clean separation between GraphQL and our business code by using decorators, so our resolvers and their methods behave just like services which can be easily unit-tested. + +## Field resolvers + +Queries and mutations are not the only type of resolvers. We often create object type field resolvers (e.g. when a `user` type has a `posts` field) which we have to resolve by fetching relational data from the database. + +Field resolvers in TypeGraphQL are very similar to queries and mutations - we create them as a method on the resolver class but with a few modifications. First we declare which object type fields we are resolving by providing the type to the `@Resolver` decorator: + +```ts +@Resolver(of => Recipe) +class RecipeResolver { + // Queries and mutations +} +``` + +Then we create a class method that will become the field resolver. +In our example we have the `averageRating` field in the `Recipe` object type that should calculate the average from the `ratings` array. + +```ts +@Resolver(of => Recipe) +class RecipeResolver { + // Queries and mutations + + averageRating(recipe: Recipe) { + // ... + } +} +``` + +We then mark the method as a field resolver with the `@FieldResolver()` decorator. Since we've already defined the field type in the `Recipe` class definition, there's no need to redefine it. We also decorate the method parameters with the `@Root` decorator in order to inject the recipe object. + +```ts +@Resolver(of => Recipe) +class RecipeResolver { + // Queries and mutations + + @FieldResolver() + averageRating(@Root() recipe: Recipe) { + // ... + } +} +``` + +For enhanced type safety we can implement the `ResolverInterface` interface. +It's a small helper that checks if the return type of the field resolver methods, like `averageRating(...)`, matches the `averageRating` property of the `Recipe` class and whether the first parameter of the method is the actual object type (`Recipe` class). + +```ts +@Resolver(of => Recipe) +class RecipeResolver implements ResolverInterface { + // Queries and mutations + + @FieldResolver() + averageRating(@Root() recipe: Recipe) { + // ... + } +} +``` + +Here is the full implementation of the sample `averageRating` field resolver: + +```ts +@Resolver(of => Recipe) +class RecipeResolver implements ResolverInterface { + // Queries and mutations + + @FieldResolver() + averageRating(@Root() recipe: Recipe) { + const ratingsSum = recipe.ratings.reduce((a, b) => a + b, 0); + return recipe.ratings.length ? ratingsSum / recipe.ratings.length : null; + } +} +``` + +For simple resolvers like `averageRating` or deprecated fields that behave like aliases, you can create field resolvers inline in the object type class definition: + +```ts +@ObjectType() +class Recipe { + @Field() + title: string; + + @Field({ deprecationReason: "Use `title` instead" }) + get name(): string { + return this.title; + } + + @Field(type => [Rate]) + ratings: Rate[]; + + @Field(type => Float, { nullable: true }) + averageRating(@Arg("since") sinceDate: Date): number | null { + const ratings = this.ratings.filter(rate => rate.date > sinceDate); + if (!ratings.length) return null; + + const ratingsSum = ratings.reduce((a, b) => a + b, 0); + return ratingsSum / ratings.length; + } +} +``` + +However, if the code is more complicated and has side effects (i.e. api calls, fetching data from a databases), a resolver class method should be used instead. This way we can leverage the dependency injection mechanism, which is really helpful in testing. For example: + +```ts +import { Repository } from "typeorm"; + +@Resolver(of => Recipe) +class RecipeResolver implements ResolverInterface { + constructor( + // Dependency injection + private readonly userRepository: Repository, + ) {} + + @FieldResolver() + async author(@Root() recipe: Recipe) { + const author = await this.userRepository.findById(recipe.userId); + if (!author) throw new SomethingWentWrongError(); + return author; + } +} +``` + +Note that if a field name of a field resolver doesn't exist in the resolver object type, it will create a field in the schema with this name. This feature is useful when the field is purely calculable (eg. `averageRating` from `ratings` array) and to avoid polluting the class signature. + +## Resolver Inheritance + +Resolver class `inheritance` is an advanced topic covered in the [resolver inheritance docs](./inheritance.md#resolvers-inheritance). + +## Examples + +These code samples are just made up for tutorial purposes. +You can find more advanced, real examples in the [examples folder on the repository](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples). diff --git a/website/versioned_docs/version-2.0.0-beta.3/scalars.md b/website/versioned_docs/version-2.0.0-beta.3/scalars.md new file mode 100644 index 000000000..ced4d34c9 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/scalars.md @@ -0,0 +1,175 @@ +--- +title: Scalars +id: version-2.0.0-beta.3-scalars +original_id: scalars +--- + +## Aliases + +TypeGraphQL provides aliases for 3 basic scalars: + +- Int --> GraphQLInt; +- Float --> GraphQLFloat; +- ID --> GraphQLID; + +This shorthand allows you to save keystrokes when declaring field types: + +```ts +// Import the aliases +import { ID, Float, Int } from "type-graphql"; + +@ObjectType() +class MysteryObject { + @Field(type => ID) + readonly id: string; + + @Field(type => Int) + notificationsCount: number; + + @Field(type => Float) + probability: number; +} +``` + +In the last case you can omit the `type => Float` since JavaScript `Number` will become `GraphQLFloat` in the schema automatically. + +Other scalars - i.e. `GraphQLString` and `GraphQLBoolean` - do not need aliases. When possible, they will be reflected automatically: + +```ts +@ObjectType() +class User { + @Field() + name: string; + + @Field() + isOld: boolean; +} +``` + +However in some cases we must explicitly declare the string/bool scalar type. Use JS constructor functions (`String`, `Boolean`) then: + +```ts +@ObjectType() +class SampleObject { + @Field(type => String, { nullable: true }) + // TS reflected type is `Object` :( + get optionalInfo(): string | undefined { + if (Math.random() > 0.5) { + return "Gotcha!"; + } + } +} +``` + +## Custom Scalars + +TypeGraphQL also supports custom scalar types! + +First of all, we need to create our own `GraphQLScalarType` instance or import a scalar type from a 3rd-party npm library. For example, Mongo's ObjectId: + +```ts +import { GraphQLScalarType, Kind } from "graphql"; +import { ObjectId } from "mongodb"; + +export const ObjectIdScalar = new GraphQLScalarType({ + name: "ObjectId", + description: "Mongo object id scalar type", + serialize(value: unknown): string { + // Check type of value + if (!(value instanceof ObjectId)) { + throw new Error("ObjectIdScalar can only serialize ObjectId values"); + } + return value.toHexString(); // Value sent to client + }, + parseValue(value: unknown): ObjectId { + // Check type of value + if (typeof value !== "string") { + throw new Error("ObjectIdScalar can only parse string values"); + } + return new ObjectId(value); // Value from client input variables + }, + parseLiteral(ast): ObjectId { + // Check type of value + if (ast.kind !== Kind.STRING) { + throw new Error("ObjectIdScalar can only parse string values"); + } + return new ObjectId(ast.value); // Value from client query + }, +}); +``` + +Then we can just use it in our field decorators: + +```ts +// Import earlier created const +import { ObjectIdScalar } from "../my-scalars/ObjectId"; + +@ObjectType() +class User { + @Field(type => ObjectIdScalar) // Explicitly use it + readonly id: ObjectId; + + @Field() + name: string; + + @Field() + isOld: boolean; +} +``` + +Optionally, we can declare the association between the reflected property type and our scalars to automatically map them (no need for explicit type annotation!): + +```ts +@ObjectType() +class User { + @Field() // Magic goes here - no type annotation for custom scalar + readonly id: ObjectId; +} +``` + +All we need to do is register the association map in the `buildSchema` options: + +```ts +import { ObjectId } from "mongodb"; +import { ObjectIdScalar } from "../my-scalars/ObjectId"; +import { buildSchema } from "type-graphql"; + +const schema = await buildSchema({ + resolvers, + scalarsMap: [{ type: ObjectId, scalar: ObjectIdScalar }], +}); +``` + +However, we must be aware that this will only work when the TypeScript reflection mechanism can handle it. So our class property type must be a `class`, not an enum, union or interface. + +## Date Scalars + +TypeGraphQL provides built-in scalars for the `Date` type. There are two versions of this scalar: + +- ISO-formatted string: `"2023-05-19T21:04:39.573Z"` +- timestamp-based number: `1518037458374` + +They are exported from the `type-graphql` package as `GraphQLISODateTime` and `GraphQLTimestamp` but comes from `graphql-scalars` npm package. + +By default, TypeGraphQL uses the ISO date format, however we can change it to timestamp format using the mentioned above `scalarsMap` option of `buildSchema` configuration: + +```ts +import { buildSchema, GraphQLTimestamp } from "type-graphql"; + +const schema = await buildSchema({ + resolvers, + scalarsMap: [{ type: Date, scalar: GraphQLTimestamp }], +}); +``` + +There's no need then to explicitly declare the field type: + +```ts +@ObjectType() +class User { + @Field() + registrationDate: Date; +} +``` + +We can of course use any other `Date` scalar from `graphql-scalars` or any other npm package. diff --git a/website/versioned_docs/version-2.0.0-beta.3/subscriptions.md b/website/versioned_docs/version-2.0.0-beta.3/subscriptions.md new file mode 100644 index 000000000..b97395791 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/subscriptions.md @@ -0,0 +1,191 @@ +--- +title: Subscriptions +id: version-2.0.0-beta.3-subscriptions +original_id: subscriptions +--- + +GraphQL can be used to perform reads with queries and writes with mutations. +However, oftentimes clients want to get updates pushed to them from the server when data they care about changes. +To support that, GraphQL has a third operation: subscription. TypeGraphQL of course has great support for subscription, using the [graphql-subscriptions](https://github.com/apollographql/graphql-subscriptions) package created by [Apollo GraphQL](https://www.apollographql.com). + +## Creating Subscriptions + +Subscription resolvers are similar to [queries and mutation resolvers](./resolvers.md) but slightly more complicated. + +First we create a normal class method as always, but this time annotated with the `@Subscription()` decorator. + +```ts +class SampleResolver { + // ... + @Subscription() + newNotification(): Notification { + // ... + } +} +``` + +Then we have to provide the topics we wish to subscribe to. This can be a single topic string, an array of topics or a function to dynamically create a topic based on subscription arguments passed to the query. We can also use TypeScript enums for enhanced type safety. + +```ts +class SampleResolver { + // ... + @Subscription({ + topics: "NOTIFICATIONS", // Single topic + topics: ["NOTIFICATIONS", "ERRORS"] // Or topics array + topics: ({ args, payload, context }) => args.topic // Or dynamic topic function + }) + newNotification(): Notification { + // ... + } +} +``` + +We can also provide the `filter` option to decide which topic events should trigger our subscription. +This function should return a `boolean` or `Promise` type. + +```ts +class SampleResolver { + // ... + @Subscription({ + topics: "NOTIFICATIONS", + filter: ({ payload, args }) => args.priorities.includes(payload.priority), + }) + newNotification(): Notification { + // ... + } +} +``` + +We can also provide a custom subscription logic which might be useful, e.g. if we want to use the Prisma subscription functionality or something similar. + +All we need to do is to use the `subscribe` option which should be a function that returns an `AsyncIterator`. Example using Prisma client subscription feature: + +```ts +class SampleResolver { + // ... + @Subscription({ + subscribe: (root, args, context, info) => { + return context.prisma.$subscribe.users({ mutation_in: [args.mutationType] }); + }, + }) + newNotification(): Notification { + // ... + } +} +``` + +> Be aware that we can't mix the `subscribe` option with the `topics` and `filter` options. If the filtering is still needed, we can use the [`withFilter` function](https://github.com/apollographql/graphql-subscriptions#filters) from the `graphql-subscriptions` package. + +Now we can implement the subscription resolver. It will receive the payload from a triggered topic of the pubsub system using the `@Root()` decorator. There, we can transform it to the returned shape. + +```ts +class SampleResolver { + // ... + @Subscription({ + topics: "NOTIFICATIONS", + filter: ({ payload, args }) => args.priorities.includes(payload.priority), + }) + newNotification( + @Root() notificationPayload: NotificationPayload, + @Args() args: NewNotificationsArgs, + ): Notification { + return { + ...notificationPayload, + date: new Date(), + }; + } +} +``` + +## Triggering subscription topics + +Ok, we've created subscriptions, but what is the `pubsub` system and how do we trigger topics? + +They might be triggered from external sources like a database but also in mutations, +e.g. when we modify some resource that clients want to receive notifications about when it changes. + +So, let us assume we have this mutation for adding a new comment: + +```ts +class SampleResolver { + // ... + @Mutation(returns => Boolean) + async addNewComment(@Arg("comment") input: CommentInput) { + const comment = this.commentsService.createNew(input); + await this.commentsRepository.save(comment); + return true; + } +} +``` + +We use the `@PubSub()` decorator to inject the `pubsub` into our method params. +There we can trigger the topics and send the payload to all topic subscribers. + +```ts +class SampleResolver { + // ... + @Mutation(returns => Boolean) + async addNewComment(@Arg("comment") input: CommentInput, @PubSub() pubSub: PubSubEngine) { + const comment = this.commentsService.createNew(input); + await this.commentsRepository.save(comment); + // Trigger subscriptions topics + const payload: NotificationPayload = { message: input.content }; + await pubSub.publish("NOTIFICATIONS", payload); + return true; + } +} +``` + +For easier testability (mocking/stubbing), we can also inject the `publish` method by itself bound to a selected topic. +This is done by using the `@PubSub("TOPIC_NAME")` decorator and the `Publisher` type: + +```ts +class SampleResolver { + // ... + @Mutation(returns => Boolean) + async addNewComment( + @Arg("comment") input: CommentInput, + @PubSub("NOTIFICATIONS") publish: Publisher, + ) { + const comment = this.commentsService.createNew(input); + await this.commentsRepository.save(comment); + // Trigger subscriptions topics + await publish({ message: input.content }); + return true; + } +} +``` + +And that's it! Now all subscriptions attached to the `NOTIFICATIONS` topic will be triggered when performing the `addNewComment` mutation. + +## Using a custom PubSub system + +By default, TypeGraphQL uses a simple `PubSub` system from `graphql-subscriptions` which is based on EventEmitter. +This solution has a big drawback in that it will work correctly only when we have a single instance (process) of our Node.js app. + +For better scalability we'll want to use one of the [`PubSub implementations`](https://github.com/apollographql/graphql-subscriptions#pubsub-implementations) backed by an external store like Redis with the [`graphql-redis-subscriptions`](https://github.com/davidyaha/graphql-redis-subscriptions) package. + +All we need to do is create an instance of PubSub according to the package instructions and then provide it to the TypeGraphQL `buildSchema` options: + +```ts +const myRedisPubSub = getConfiguredRedisPubSub(); + +const schema = await buildSchema({ + resolvers: [ExampleResolver], + pubSub: myRedisPubSub, +}); +``` + +## Creating a Subscription Server + +The [bootstrap guide](./bootstrap.md) and all the earlier examples used [`apollo-server`](https://github.com/apollographql/apollo-server) to create an HTTP endpoint for our GraphQL API. + +However, beginning in Apollo Server 3, subscriptions are not supported by the "batteries-included" apollo-server package. To enable subscriptions, you need to follow the guide on their docs page: + + +## Examples + +See how subscriptions work in a [simple example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/simple-subscriptions). + +For production usage, it's better to use something more scalable like a Redis-based pubsub system - [a working example is also available](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/redis-subscriptions). +However, to launch this example you need to have a running instance of Redis and you might have to modify the example code to provide your connection parameters. diff --git a/website/versioned_docs/version-2.0.0-beta.3/types-and-fields.md b/website/versioned_docs/version-2.0.0-beta.3/types-and-fields.md new file mode 100644 index 000000000..541da096b --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/types-and-fields.md @@ -0,0 +1,140 @@ +--- +title: Types and Fields +id: version-2.0.0-beta.3-types-and-fields +original_id: types-and-fields +--- + +The main idea of TypeGraphQL is to automatically create GraphQL schema definitions from TypeScript classes. To avoid the need for schema definition files and interfaces describing the schema, we use decorators and a bit of reflection magic. + +Let's start by defining our example TypeScript class which represents our `Recipe` model with fields for storing the recipe data: + +```ts +class Recipe { + id: string; + title: string; + ratings: Rate[]; + averageRating?: number; +} +``` + +The first thing we must do is decorate the class with the `@ObjectType` decorator. It marks the class as the `type` known from the GraphQL SDL or `GraphQLObjectType` from `graphql-js`: + +```ts +@ObjectType() +class Recipe { + id: string; + title: string; + ratings: Rate[]; + averageRating: number; +} +``` + +Then we declare which class properties should be mapped to the GraphQL fields. +To do this, we use the `@Field` decorator, which is also used to collect metadata from the TypeScript reflection system: + +```ts +@ObjectType() +class Recipe { + @Field() + id: string; + + @Field() + title: string; + + @Field() + ratings: Rate[]; + + @Field() + averageRating: number; +} +``` + +For simple types (like `string` or `boolean`) this is all that's needed but due to a limitation in TypeScript's reflection, we need to provide info about generic types (like `Array` or `Promise`). So to declare the `Rate[]` type, we have to use the explicit `[ ]` syntax for array types - `@Field(type => [Rate])`. +For nested arrays, we just use the explicit `[ ]` notation to determine the depth of the array, e.g. `@Field(type => [[Int]])` would tell the compiler we expect an integer array of depth 2. + +Why use function syntax and not a simple `{ type: Rate }` config object? Because, by using function syntax we solve the problem of circular dependencies (e.g. Post <--> User), so it was adopted as a convention. You can use the shorthand syntax `@Field(() => Rate)` if you want to save some keystrokes but it might be less readable for others. + +By default, all fields are non nullable, just like properties in TypeScript. However, you can change that behavior by providing `nullableByDefault: true` option in `buildSchema` settings, described in [bootstrap guide](./bootstrap.md). + +So for nullable properties like `averageRating` which might not be defined when a recipe has no ratings yet, we mark the class property as optional with a `?:` operator and also have to pass the `{ nullable: true }` decorator parameter. We should be aware that when we declare our type as a nullable union (e.g. `string | null`), we need to explicitly provide the type to the `@Field` decorator. + +In the case of lists, we may also need to define their nullability in a more detailed form. The basic `{ nullable: true | false }` setting only applies to the whole list (`[Item!]` or `[Item!]!`), so if we need a sparse array, we can control the list items' nullability via `nullable: "items"` (for `[Item]!`) or `nullable: "itemsAndList"` (for the `[Item]`) option. Be aware that setting `nullableByDefault: true` option will also apply to lists, so it will produce `[Item]` type, just like with `nullable: "itemsAndList"`. + +For nested lists, those options apply to the whole depth of the array: `@Field(() => [[Item]]` would by default produce `[[Item!]!]!`, setting `nullable: "itemsAndList"` would produce `[[Item]]` while `nullable: "items"` would produce `[[Item]]!` + +In the config object we can also provide the `description` and `deprecationReason` properties for GraphQL schema purposes. + +So after these changes our example class would look like this: + +```ts +@ObjectType({ description: "The recipe model" }) +class Recipe { + @Field(type => ID) + id: string; + + @Field({ description: "The title of the recipe" }) + title: string; + + @Field(type => [Rate]) + ratings: Rate[]; + + @Field({ nullable: true }) + averageRating?: number; +} +``` + +Which will result in generating the following part of the GraphQL schema in SDL: + +```graphql +type Recipe { + id: ID! + title: String! + ratings: [Rate!]! + averageRating: Float +} +``` + +Similarly, the `Rate` type class would look like this: + +```ts +@ObjectType() +class Rate { + @Field(type => Int) + value: number; + + @Field() + date: Date; + + user: User; +} +``` + +which results in this equivalent of the GraphQL SDL: + +```graphql +type Rate { + value: Int! + date: Date! +} +``` + +As we can see, for the `id` property of `Recipe` we passed `type => ID` and for the `value` field of `Rate` we passed `type => Int`. This way we can overwrite the inferred type from the reflection metadata. We can read more about the ID and Int scalars in [the scalars docs](./scalars.md). There is also a section about the built-in `Date` scalar. + +Also the `user` property doesn't have a `@Field()` decorator - this way we can hide some properties of our data model. In this case, we need to store the `user` field of the `Rate` object to the database in order to prevent multiple rates, but we don't want to make it publicly accessible. + +Note that if a field of an object type is purely calculable (e.g. `averageRating` from `ratings` array) and we don't want to pollute the class signature, we can omit it and just implement the field resolver (described in [resolvers doc](./resolvers.md)). + +Be aware that **defining constructors is strictly forbidden** and we shouldn't use them there, as TypeGraphQL creates instances of object type classes under the hood by itself. + +In some case we may want to expose our classes or properties under a different types or fields name. +To accomplish this, we can use the `name` parameter or `name` property of decorator's options, e.g.: + +```ts +@ObjectType("ExternalTypeName") +class InternalClassName { + @Field({ name: "externalFieldName" }) + internalPropertyName: string; +} +``` + +However, be aware that renaming fields works only for output types like object type or interface type. It's due to a fact that input fields has no resolvers that could translate one field value into another property value. diff --git a/website/versioned_docs/version-2.0.0-beta.3/unions.md b/website/versioned_docs/version-2.0.0-beta.3/unions.md new file mode 100644 index 000000000..dcab4790a --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/unions.md @@ -0,0 +1,109 @@ +--- +title: Unions +id: version-2.0.0-beta.3-unions +original_id: unions +--- + +Sometimes our API has to be flexible and return a type that is not specific but one from a range of possible types. An example might be a movie site's search functionality: using the provided phrase we search the database for movies but also actors. So the query has to return a list of `Movie` or `Actor` types. + +Read more about the GraphQL Union Type in the [official GraphQL docs](http://graphql.org/learn/schema/#union-types). + +## Usage + +Let's start by creating the object types from the example above: + +```ts +@ObjectType() +class Movie { + @Field() + name: string; + + @Field() + rating: number; +} +``` + +```ts +@ObjectType() +class Actor { + @Field() + name: string; + + @Field(type => Int) + age: number; +} +``` + +Now let's create an union type from the object types above - the rarely seen `[ ] as const` syntax is to inform TypeScript compiler that it's a tuple, which allows for better TS union type inference: + +```ts +import { createUnionType } from "type-graphql"; + +const SearchResultUnion = createUnionType({ + name: "SearchResult", // Name of the GraphQL union + types: () => [Movie, Actor] as const, // function that returns tuple of object types classes +}); +``` + +Then we can use the union type in the query by providing the `SearchResultUnion` value in the `@Query` decorator return type annotation. +Notice, that we have to explicitly use the decorator return type annotation due to TypeScript's reflection limitations. +For TypeScript compile-time type safety we can also use `typeof SearchResultUnion` which is equal to type `Movie | Actor`. + +```ts +@Resolver() +class SearchResolver { + @Query(returns => [SearchResultUnion]) + async search(@Arg("phrase") phrase: string): Promise> { + const movies = await Movies.findAll(phrase); + const actors = await Actors.findAll(phrase); + + return [...movies, ...actors]; + } +} +``` + +## Resolving Type + +Be aware that when the query/mutation return type (or field type) is a union, we have to return a specific instance of the object type class. Otherwise, `graphql-js` will not be able to detect the underlying GraphQL type correctly when we use plain JS objects. + +However, we can also provide our own `resolveType` function implementation to the `createUnionType` options. This way we can return plain objects in resolvers and then determine the returned object type by checking the shape of the data object, e.g.: + +```ts +const SearchResultUnion = createUnionType({ + name: "SearchResult", + types: () => [Movie, Actor] as const, + // Implementation of detecting returned object type + resolveType: value => { + if ("rating" in value) { + return Movie; // Return object type class (the one with `@ObjectType()`) + } + if ("age" in value) { + return "Actor"; // Or the schema name of the type as a string + } + return undefined; + }, +}); +``` + +**Et VoilΓ !** We can now build the schema and make the example query πŸ˜‰ + +```graphql +query { + search(phrase: "Holmes") { + ... on Actor { + # Maybe Katie Holmes? + name + age + } + ... on Movie { + # For sure Sherlock Holmes! + name + rating + } + } +} +``` + +## Examples + +More advanced usage examples of unions (and enums) are located in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/enums-and-unions). diff --git a/website/versioned_docs/version-2.0.0-beta.3/validation.md b/website/versioned_docs/version-2.0.0-beta.3/validation.md new file mode 100644 index 000000000..674115459 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.3/validation.md @@ -0,0 +1,237 @@ +--- +title: Argument and Input validation +sidebar_label: Validation +id: version-2.0.0-beta.3-validation +original_id: validation +--- + +## Scalars + +The standard way to ensure that inputs and arguments are correct, such as an `email` field that really contains a proper e-mail address, is to use [custom scalars](./scalars.md) e.g. `GraphQLEmail` from [`graphql-custom-types`](https://github.com/stylesuxx/graphql-custom-types). However, creating scalars for all single cases of data types (credit card number, base64, IP, URL) might be cumbersome. + +That's why TypeGraphQL has built-in support for argument and input validation. +By default, we can use the [`class-validator`](https://github.com/typestack/class-validator) library and easily declare the requirements for incoming data (e.g. a number is in the range 0-255 or a password that is longer than 8 characters) thanks to the awesomeness of decorators. + +We can also use other libraries or our own custom solution, as described in [custom validators](#custom-validator) section. + +## `class-validator` + +### How to use + +First, we need to install the `class-validator` package: + +```sh +npm install class-validator +``` + +Then we decorate the input/arguments class with the appropriate decorators from `class-validator`. +So we take this: + +```ts +@InputType() +export class RecipeInput { + @Field() + title: string; + + @Field({ nullable: true }) + description?: string; +} +``` + +...and turn it into this: + +```ts +import { MaxLength, Length } from "class-validator"; + +@InputType() +export class RecipeInput { + @Field() + @MaxLength(30) + title: string; + + @Field({ nullable: true }) + @Length(30, 255) + description?: string; +} +``` + +Then we need to enable the auto-validate feature (as it's disabled by default) by simply setting `validate: true` in `buildSchema` options, e.g.: + +```ts +const schema = await buildSchema({ + resolvers: [RecipeResolver], + validate: true, // Enable 'class-validator' integration +}); +``` + +And that's it! πŸ˜‰ + +TypeGraphQL will automatically validate our inputs and arguments based on the definitions: + +```ts +@Resolver(of => Recipe) +export class RecipeResolver { + @Mutation(returns => Recipe) + async addRecipe(@Arg("input") recipeInput: RecipeInput): Promise { + // 100% sure that the input is correct + console.assert(recipeInput.title.length <= 30); + console.assert(recipeInput.description.length >= 30); + console.assert(recipeInput.description.length <= 255); + } +} +``` + +Of course, [there are many more decorators](https://github.com/typestack/class-validator#validation-decorators) we have access to, not just the simple `@Length` decorator used in the example above, so take a look at the `class-validator` documentation. + +This feature is enabled by default. However, we can disable it if we must: + +```ts +const schema = await buildSchema({ + resolvers: [RecipeResolver], + validate: false, // Disable automatic validation or pass the default config object +}); +``` + +And we can still enable it per resolver's argument if we need to: + +```ts +class RecipeResolver { + @Mutation(returns => Recipe) + async addRecipe(@Arg("input", { validate: true }) recipeInput: RecipeInput) { + // ... + } +} +``` + +The `ValidatorOptions` object used for setting features like [validation groups](https://github.com/typestack/class-validator#validation-groups) can also be passed: + +```ts +class RecipeResolver { + @Mutation(returns => Recipe) + async addRecipe( + @Arg("input", { validate: { groups: ["admin"] } }) + recipeInput: RecipeInput, + ) { + // ... + } +} +``` + +Note that by default, the `skipMissingProperties` setting of the `class-validator` is set to `true` because GraphQL will independently check whether the params/fields exist or not. +Same goes to `forbidUnknownValues` setting which is set to `false` because the GraphQL runtime checks for additional data, not described in schema. + +GraphQL will also check whether the fields have correct types (String, Int, Float, Boolean, etc.) so we don't have to use the `@IsOptional`, `@Allow`, `@IsString` or the `@IsInt` decorators at all! + +However, when using nested input or arrays, we always have to use [`@ValidateNested()` decorator](https://github.com/typestack/class-validator#validating-nested-objects) or [`{ each: true }` option](https://github.com/typestack/class-validator#validating-arrays) to make nested validation work properly. + +### Response to the Client + +When a client sends incorrect data to the server: + +```graphql +mutation ValidationMutation { + addRecipe( + input: { + # Too long! + title: "Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet" + } + ) { + title + creationDate + } +} +``` + +the [`ArgumentValidationError`](https://github.com/MichalLytek/type-graphql/blob/master/src/errors/ArgumentValidationError.ts) will be thrown. + +By default, the `apollo-server` package from the [bootstrap guide](./bootstrap.md) will format the error to match the `GraphQLFormattedError` interface. So when the `ArgumentValidationError` occurs, the client will receive this JSON with a nice `validationErrors` property inside of `extensions.exception`: + +```json +{ + "errors": [ + { + "message": "Argument Validation Error", + "locations": [ + { + "line": 2, + "column": 3 + } + ], + "path": ["addRecipe"], + "extensions": { + "code": "INTERNAL_SERVER_ERROR", + "exception": { + "validationErrors": [ + { + "target": { + "title": "Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet" + }, + "value": "Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet", + "property": "title", + "children": [], + "constraints": { + "maxLength": "title must be shorter than or equal to 30 characters" + } + } + ], + "stacktrace": [ + "Error: Argument Validation Error", + " at Object. (/type-graphql/src/resolvers/validate-arg.ts:29:11)", + " at Generator.throw ()", + " at rejected (/type-graphql/node_modules/tslib/tslib.js:105:69)", + " at processTicksAndRejections (internal/process/next_tick.js:81:5)" + ] + } + } + } + ], + "data": null +} +``` + +Of course we can also create our own custom implementation of the `formatError` function provided in the `ApolloServer` config options which will transform the `GraphQLError` with a `ValidationError` array in the desired output format (e.g. `extensions.code = "ARGUMENT_VALIDATION_ERROR"`). + +### Automatic Validation Example + +To see how this works, check out the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/automatic-validation). + +### Caveats + +Even if we don't use the validation feature (and we have provided `{ validate: false }` option to `buildSchema`), we still need to have `class-validator` installed as a dev dependency in order to compile our app without errors using `tsc`. + +An alternative solution that allows to completely get rid off big `class-validator` from our project's `node_modules` folder is to suppress the `error TS2307: Cannot find module 'class-validator'` TS error by providing `"skipLibCheck": true` setting in `tsconfig.json`. + +## Custom validator + +We can also use other libraries than `class-validator` together with TypeGraphQL. + +To integrate it, all we need to do is to provide a custom function as `validate` option in `buildSchema`. +It receives two parameters: + +- `argValue` which is the injected value of `@Arg()` or `@Args()` +- `argType` which is a runtime type information (e.g. `String` or `RecipeInput`). + +The `validateFn` option can be an async function and should return nothing (`void`) when validation passes or throw an error when validation fails. +So be aware of this while trying to wrap another library in `validateFn` function for TypeGraphQL. + +Example using [decorators library for Joi validators (`joiful`)](https://github.com/joiful-ts/joiful): + +```ts +const schema = await buildSchema({ + // ... + validate: argValue => { + // Call joiful validate + const { error } = joiful.validate(argValue); + if (error) { + // Throw error on failed validation + throw error; + } + }, +}); +``` + +> Be aware that when using custom validator, the error won't be wrapped with `ArgumentValidationError` like for the built-in `class-validator` validation. + +### Custom Validation Example + +To see how this works, check out the [simple custom validation integration example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.3/examples/custom-validation). diff --git a/website/versioned_docs/version-2.0.0-beta.4/authorization.md b/website/versioned_docs/version-2.0.0-beta.4/authorization.md new file mode 100644 index 000000000..3e381b331 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.4/authorization.md @@ -0,0 +1,195 @@ +--- +title: Authorization +id: version-2.0.0-beta.4-authorization +original_id: authorization +--- + +Authorization is a core feature used in almost all APIs. Sometimes we want to restrict data access or actions for a specific group of users. + +In express.js (and other Node.js frameworks) we use middleware for this, like `passport.js` or the custom ones. However, in GraphQL's resolver architecture we don't have middleware so we have to imperatively call the auth checking function and manually pass context data to each resolver, which might be a bit tedious. + +That's why authorization is a first-class feature in `TypeGraphQL`! + +## How to use + +First, we need to use the `@Authorized` decorator as a guard on a field, query or mutation. +Example object type field guards: + +```ts +@ObjectType() +class MyObject { + @Field() + publicField: string; + + @Authorized() + @Field() + authorizedField: string; + + @Authorized("ADMIN") + @Field() + adminField: string; + + @Authorized(["ADMIN", "MODERATOR"]) + @Field({ nullable: true }) + hiddenField?: string; +} +``` + +We can leave the `@Authorized` decorator brackets empty or we can specify the role/roles that the user needs to possess in order to get access to the field, query or mutation. +By default the roles are of type `string` but they can easily be changed as the decorator is generic - `@Authorized(1, 7, 22)`. + +Thus, authorized users (regardless of their roles) can only read the `publicField` or the `authorizedField` from the `MyObject` object. They will receive `null` when accessing the `hiddenField` field and will receive an error (that will propagate through the whole query tree looking for a nullable field) for the `adminField` when they don't satisfy the role constraints. + +Sample query and mutation guards: + +```ts +@Resolver() +class MyResolver { + @Query() + publicQuery(): MyObject { + return { + publicField: "Some public data", + authorizedField: "Data for logged users only", + adminField: "Top secret info for admin", + }; + } + + @Authorized() + @Query() + authedQuery(): string { + return "Authorized users only!"; + } + + @Authorized("ADMIN", "MODERATOR") + @Mutation() + adminMutation(): string { + return "You are an admin/moderator, you can safely drop the database ;)"; + } +} +``` + +Authorized users (regardless of their roles) will be able to read data from the `publicQuery` and the `authedQuery` queries, but will receive an error when trying to perform the `adminMutation` when their roles don't include `ADMIN` or `MODERATOR`. + +Next, we need to create our auth checker function. Its implementation may depend on our business logic: + +```ts +export const customAuthChecker: AuthChecker = ( + { root, args, context, info }, + roles, +) => { + // Read user from context + // and check the user's permission against the `roles` argument + // that comes from the '@Authorized' decorator, eg. ["ADMIN", "MODERATOR"] + + return true; // or 'false' if access is denied +}; +``` + +The second argument of the `AuthChecker` generic type is `RoleType` - used together with the `@Authorized` decorator generic type. + +Auth checker can be also defined as a class - this way we can leverage the dependency injection mechanism: + +```ts +export class CustomAuthChecker implements AuthCheckerInterface { + constructor( + // Dependency injection + private readonly userRepository: Repository, + ) {} + + check({ root, args, context, info }: ResolverData, roles: string[]) { + const userId = getUserIdFromToken(context.token); + // Use injected service + const user = this.userRepository.getById(userId); + + // Custom logic, e.g.: + return user % 2 === 0; + } +} +``` + +The last step is to register the function or class while building the schema: + +```ts +import { customAuthChecker } from "../auth/custom-auth-checker.ts"; + +const schema = await buildSchema({ + resolvers: [MyResolver], + // Register the auth checking function + // or defining it inline + authChecker: customAuthChecker, +}); +``` + +And it's done! πŸ˜‰ + +If we need silent auth guards and don't want to return authorization errors to users, we can set the `authMode` property of the `buildSchema` config object to `"null"`: + +```ts +const schema = await buildSchema({ + resolvers: ["./**/*.resolver.ts"], + authChecker: customAuthChecker, + authMode: "null", +}); +``` + +It will then return `null` instead of throwing an authorization error. + +## Recipes + +We can also use `TypeGraphQL` with JWT authentication. +Here's an example using `@apollo/server`: + +```ts +import { ApolloServer } from "@apollo/server"; +import { expressMiddleware } from "@apollo/server/express4"; +import express from "express"; +import jwt from "express-jwt"; +import bodyParser from "body-parser"; +import { schema } from "./graphql/schema"; +import { User } from "./User.type"; + +// GraphQL path +const GRAPHQL_PATH = "/graphql"; + +// GraphQL context +type Context = { + user?: User; +}; + +// Express +const app = express(); + +// Apollo server +const server = new ApolloServer({ schema }); +await server.start(); + +// Mount a JWT or other authentication middleware that is run before the GraphQL execution +app.use( + GRAPHQL_PATH, + jwt({ + secret: "TypeGraphQL", + credentialsRequired: false, + }), +); + +// Apply GraphQL server middleware +app.use( + GRAPHQL_PATH, + bodyParser.json(), + expressMiddleware(server, { + // Build context + // 'req.user' comes from 'express-jwt' + context: async ({ req }) => ({ user: req.user }), + }), +); + +// Start server +await new Promise(resolve => app.listen({ port: 4000 }, resolve)); +console.log(`GraphQL server ready at http://localhost:4000/${GRAPHQL_PATH}`); +``` + +Then we can use standard, token based authorization in the HTTP header like in classic REST APIs and take advantage of the `TypeGraphQL` authorization mechanism. + +## Example + +See how this works in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/authorization). diff --git a/website/versioned_docs/version-2.0.0-beta.4/aws-lambda.md b/website/versioned_docs/version-2.0.0-beta.4/aws-lambda.md new file mode 100644 index 000000000..a2513a23c --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.4/aws-lambda.md @@ -0,0 +1,37 @@ +--- +title: AWS Lambda integration +id: version-2.0.0-beta.4-aws-lambda +original_id: aws-lambda +--- + +## Using TypeGraphQL in AWS Lambda environment + +AWS Lambda environment is a bit different than a standard Node.js server deployment. + +However, the only tricky part with the setup is that we need to "cache" the built schema, to save some computing time by avoiding rebuilding the schema on every request to our lambda. + +So all we need to do is to assign the built schema to the local variable using the `??=` conditional assignment operator. +We can do the same thing for `ApolloServer`. + +Below you you can find the full snippet for the AWS Lambda integration: + +```ts +import { APIGatewayProxyHandlerV2 } from "aws-lambda"; +import { ApolloServer } from "apollo-server-lambda"; + +let cachedSchema: GraphQLSchema | null = null; +let cachedServer: ApolloServer | null = null; + +export const handler: APIGatewayProxyHandlerV2 = async (event, context, callback) => { + // build TypeGraphQL executable schema only once, then read it from local "cached" variable + cachedSchema ??= await buildSchema({ + resolvers: [RecipeResolver], + }); + + // create the GraphQL server only once + cachedServer ??= new ApolloServer({ schema: cachedSchema }); + + // make a handler for `aws-lambda` + return cachedServer.createHandler({})(event, context, callback); +}; +``` diff --git a/website/versioned_docs/version-2.0.0-beta.4/browser-usage.md b/website/versioned_docs/version-2.0.0-beta.4/browser-usage.md new file mode 100644 index 000000000..50cb8ba43 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.4/browser-usage.md @@ -0,0 +1,40 @@ +--- +title: Browser usage +id: version-2.0.0-beta.4-browser-usage +original_id: browser-usage +--- + +## Using classes in a client app + +Sometimes we might want to use the classes we've created and annotated with TypeGraphQL decorators, in our client app that works in the browser. For example, reusing the args or input classes with `class-validator` decorators or the object type classes with some helpful custom methods. + +Since TypeGraphQL is a Node.js framework, it doesn't work in a browser environment, so we may quickly get an error, e.g. `ERROR in ./node_modules/fs.realpath/index.js` or `utils1_promisify is not a function`, while trying to build our app with Webpack. To correct this, we have to configure Webpack to use the decorator shim instead of the normal module. We simply add this plugin code to our webpack config: + +```js +module.exports = { + // ... Rest of Webpack configuration + plugins: [ + // ... Other existing plugins + new webpack.NormalModuleReplacementPlugin(/type-graphql$/, resource => { + resource.request = resource.request.replace(/type-graphql/, "type-graphql/shim"); + }), + ]; +} +``` + +In case of cypress, you can adapt the same webpack config trick just by applying the [cypress-webpack-preprocessor](https://github.com/cypress-io/cypress-webpack-preprocessor) plugin. + +However, in some TypeScript projects like the ones using Angular, which AoT compiler requires that a full `*.ts` file is provided instead of just a `*.js` and `*.d.ts` files, to use this shim we have to simply set up our TypeScript configuration in `tsconfig.json` to use this file instead of a normal TypeGraphQL module: + +```json +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "type-graphql": ["./node_modules/type-graphql/build/typings/shim.ts"] + } + } +} +``` + +Thanks to this, our bundle will be much lighter as we don't need to embed the whole TypeGraphQL library code in our app. diff --git a/website/versioned_docs/version-2.0.0-beta.4/complexity.md b/website/versioned_docs/version-2.0.0-beta.4/complexity.md new file mode 100644 index 000000000..5ceba3420 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.4/complexity.md @@ -0,0 +1,103 @@ +--- +title: Query complexity +id: version-2.0.0-beta.4-complexity +original_id: complexity +--- + +A single GraphQL query can potentially generate a huge workload for a server, like thousands of database operations which can be used to cause DDoS attacks. In order to limit and keep track of what each GraphQL operation can do, `TypeGraphQL` provides the option of integrating with Query Complexity tools like [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity). + +This cost analysis-based solution is very promising, since we can define a β€œcost” per field and then analyze the AST to estimate the total cost of the GraphQL query. Of course all the analysis is handled by `graphql-query-complexity`. + +All we must do is define our complexity cost for the fields, mutations or subscriptions in `TypeGraphQL` and implement `graphql-query-complexity` in whatever GraphQL server that is being used. + +## How to use + +First, we need to pass `complexity` as an option to the decorator on a field, query or mutation. + +Example of complexity + +```ts +@ObjectType() +class MyObject { + @Field({ complexity: 2 }) + publicField: string; + + @Field({ complexity: ({ args, childComplexity }) => childComplexity + 1 }) + complexField: string; +} +``` + +The `complexity` option may be omitted if the complexity value is 1. +Complexity can be passed as an option to any `@Field`, `@FieldResolver`, `@Mutation` or `@Subscription` decorator. If both `@FieldResolver` and `@Field` decorators of the same property have complexity defined, then the complexity passed to the field resolver decorator takes precedence. + +In the next step, we will integrate `graphql-query-complexity` with the server that expose our GraphQL schema over HTTP. +You can use it with `express-graphql` like [in the lib examples](https://github.com/slicknode/graphql-query-complexity/blob/b6a000c0984f7391f3b4e886e3df6a7ed1093b07/README.md#usage-with-express-graphql), however we will use Apollo Server like in our other examples: + +```ts +async function bootstrap() { + // ... Build GraphQL schema + + // Create GraphQL server + const server = new ApolloServer({ + schema, + // Create a plugin to allow query complexity calculation for every request + plugins: [ + { + requestDidStart: async () => ({ + async didResolveOperation({ request, document }) { + /** + * Provides GraphQL query analysis to be able to react on complex queries to the GraphQL server + * It can be used to protect the GraphQL server against resource exhaustion and DoS attacks + * More documentation can be found at https://github.com/ivome/graphql-query-complexity + */ + const complexity = getComplexity({ + // GraphQL schema + schema, + // To calculate query complexity properly, + // check only the requested operation + // not the whole document that may contains multiple operations + operationName: request.operationName, + // GraphQL query document + query: document, + // GraphQL query variables + variables: request.variables, + // Add any number of estimators. The estimators are invoked in order, the first + // numeric value that is being returned by an estimator is used as the field complexity + // If no estimator returns a value, an exception is raised + estimators: [ + // Using fieldExtensionsEstimator is mandatory to make it work with type-graphql + fieldExtensionsEstimator(), + // Add more estimators here... + // This will assign each field a complexity of 1 + // if no other estimator returned a value + simpleEstimator({ defaultComplexity: 1 }), + ], + }); + + // React to the calculated complexity, + // like compare it with max and throw error when the threshold is reached + if (complexity > MAX_COMPLEXITY) { + throw new Error( + `Sorry, too complicated query! ${complexity} exceeded the maximum allowed complexity of ${MAX_COMPLEXITY}`, + ); + } + console.log("Used query complexity points:", complexity); + }, + }), + }, + ], + }); + + // Start server + const { url } = await startStandaloneServer(server, { listen: { port: 4000 } }); + console.log(`GraphQL server ready at ${url}`); +} +``` + +And it's done! πŸ˜‰ + +For more info about how query complexity is computed, please visit [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity). + +## Example + +See how this works in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/query-complexity). diff --git a/website/versioned_docs/version-2.0.0-beta.4/custom-decorators.md b/website/versioned_docs/version-2.0.0-beta.4/custom-decorators.md new file mode 100644 index 000000000..6995481b0 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.4/custom-decorators.md @@ -0,0 +1,109 @@ +--- +title: Custom decorators +id: version-2.0.0-beta.4-custom-decorators +original_id: custom-decorators +--- + +Custom decorators are a great way to reduce the boilerplate and reuse some common logic between different resolvers. TypeGraphQL supports two kinds of custom decorators - method and parameter. + +## Method decorators + +Using [middlewares](./middlewares.md) allows to reuse some code between resolvers. To further reduce the boilerplate and have a nicer API, we can create our own custom method decorators. + +They work in the same way as the [reusable middleware function](./middlewares.md#reusable-middleware), however, in this case we need to call `createMethodDecorator` helper function with our middleware logic and return its value: + +```ts +export function ValidateArgs(schema: JoiSchema) { + return createMethodDecorator(async ({ args }, next) => { + // Middleware code that uses custom decorator arguments + + // e.g. Validation logic based on schema using 'joi' + await joiValidate(schema, args); + return next(); + }); +} +``` + +The usage is then very simple, as we have a custom, descriptive decorator - we just place it above the resolver/field and pass the required arguments to it: + +```ts +@Resolver() +export class RecipeResolver { + @ValidateArgs(MyArgsSchema) // Custom decorator + @UseMiddleware(ResolveTime) // Explicit middleware + @Query() + randomValue(@Args() { scale }: MyArgs): number { + return Math.random() * scale; + } +} +``` + +## Parameter decorators + +Parameter decorators are just like the custom method decorators or middlewares but with an ability to return some value that will be injected to the method as a parameter. Thanks to this, it reduces the pollution in `context` which was used as a workaround for the communication between reusable middlewares and resolvers. + +They might be just a simple data extractor function, that makes our resolver more unit test friendly: + +```ts +function CurrentUser() { + return createParamDecorator(({ context }) => context.currentUser); +} +``` + +Or might be a more advanced one that performs some calculations and encapsulates some logic. Compared to middlewares, they allows for a more granular control on executing the code, like calculating fields map based on GraphQL info only when it's really needed (requested by using the `@Fields()` decorator): + +```ts +function Fields(level = 1): ParameterDecorator { + return createParamDecorator(async ({ info }) => { + const fieldsMap: FieldsMap = {}; + // Calculate an object with info about requested fields + // based on GraphQL 'info' parameter of the resolver and the level parameter + // or even call some async service, as it can be a regular async function and we can just 'await' + return fieldsMap; + }); +} +``` + +> Be aware, that `async` function as a custom param decorators logic can make the GraphQL resolver execution slower, so try to avoid them, if possible. + +Then we can use our custom param decorators in the resolvers just like the built-in decorators: + +```ts +@Resolver() +export class RecipeResolver { + constructor(private readonly recipesRepository: Repository) {} + + @Authorized() + @Mutation(returns => Recipe) + async addRecipe( + @Args() recipeData: AddRecipeInput, + // Custom decorator just like the built-in one + @CurrentUser() currentUser: User, + ) { + const recipe: Recipe = { + ...recipeData, + // and use the data returned from custom decorator in the resolver code + author: currentUser, + }; + await this.recipesRepository.save(recipe); + + return recipe; + } + + @Query(returns => Recipe, { nullable: true }) + async recipe( + @Arg("id") id: string, + // Custom decorator that parses the fields from GraphQL query info + @Fields() fields: FieldsMap, + ) { + return await this.recipesRepository.find(id, { + // use the fields map as a select projection to optimize db queries + select: fields, + }); + } +} +``` + +## Example + +See how different kinds of custom decorators work in the [custom decorators and middlewares example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/middlewares-custom-decorators). diff --git a/website/versioned_docs/version-2.0.0-beta.4/dependency-injection.md b/website/versioned_docs/version-2.0.0-beta.4/dependency-injection.md new file mode 100644 index 000000000..3a031b5dd --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.4/dependency-injection.md @@ -0,0 +1,180 @@ +--- +title: Dependency injection +id: version-2.0.0-beta.4-dependency-injection +original_id: dependency-injection +--- + +Dependency injection is a really useful pattern that helps in decoupling parts of the app. + +TypeGraphQL supports this technique by allowing users to provide their IoC container that will be used by the framework. + +## Basic usage + +The usage of this feature is very simple - all you need to do is register a 3rd party container. + +Example using TypeDI: + +```ts +import { buildSchema } from "type-graphql"; +// IOC container +import { Container } from "typedi"; +import { SampleResolver } from "./resolvers"; + +// Build TypeGraphQL executable schema +const schema = await buildSchema({ + // Array of resolvers + resolvers: [SampleResolver], + // Registry 3rd party IOC container + container: Container, +}); +``` + +Resolvers will then be able to declare their dependencies and TypeGraphQL will use the container to solve them: + +```ts +import { Service } from "typedi"; + +@Service() +@Resolver(of => Recipe) +export class RecipeResolver { + constructor( + // Dependency injection + private readonly recipeService: RecipeService, + ) {} + + @Query(returns => Recipe, { nullable: true }) + async recipe(@Arg("recipeId") recipeId: string) { + // Usage of the injected service + return this.recipeService.getOne(recipeId); + } +} +``` + +A sample recipe service implementation may look like this: + +```ts +import { Service, Inject } from "typedi"; + +@Service() +export class RecipeService { + @Inject("SAMPLE_RECIPES") + private readonly items: Recipe[], + + async getAll() { + return this.items; + } + + async getOne(id: string) { + return this.items.find(item => item.id === id); + } +} +``` + +> Be aware than when you use [InversifyJS](https://github.com/inversify/InversifyJS), you have to bind the resolver class with the [self-binding of concrete types](https://github.com/inversify/InversifyJS/blob/master/wiki/classes_as_id.md#self-binding-of-concrete-types), e.g.: +> +> ```ts +> container.bind(SampleResolver).to(SampleResolver).inSingletonScope(); +> ``` + +## Scoped containers + +Dependency injection is a really powerful pattern, but some advanced users may encounter the need for creating fresh instances of some services or resolvers for every request. Since `v0.13.0`, **TypeGraphQL** supports this feature, that is extremely useful for tracking logs by individual requests or managing stateful services. + +To register a scoped container, we need to make some changes in the server bootstrapping config code. +First we need to provide a container resolver function. It takes the resolver data (like context) as an argument and should return an instance of the container scoped to the request. + +For simple container libraries we may define it inline, e.g. using `TypeDI`: + +```ts +await buildSchema({ + container: (({ context }: ResolverData) => Container.of(context.requestId)); +}; +``` + +The tricky part is where the `context.requestId` comes from. Unfortunately, we need to provide it manually using hooks that are exposed by HTTP GraphQL middleware like `express-graphql`, `@apollo/server` or `graphql-yoga`. + +For some other advanced libraries, we might need to create an instance of the container, place it in the context object and then retrieve it in the `container` getter function: + +```ts +await buildSchema({ + container: (({ context }: ResolverData) => context.container); +}; +``` + +Example using `TypeDI` and `@apollo/server` with the `context` creation method: + +```ts +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { Container } from "typedi"; + +// Create GraphQL server +const server = new ApolloServer({ + // GraphQL schema + schema, +}); + +// Start server +const { url } = await startStandaloneServer(server, { + listen: { port: 4000 }, + // Provide unique context with 'requestId' for each request + context: async () => { + const requestId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // uuid-like + const container = Container.of(requestId.toString()); // Get scoped container + const context = { requestId, container }; // Create context + container.set("context", context); // Set context or other data in container + + return context; + }, +}); +console.log(`GraphQL server ready at ${url}`); +``` + +We also have to dispose the container after the request has been handled and the response is ready. Otherwise, there would be a huge memory leak as the new instances of services and resolvers have been created for each request but they haven't been cleaned up. + +Apollo Server has a [plugins](https://www.apollographql.com/docs/apollo-server/integrations/plugins) feature that supports [`willSendResponse`](https://www.apollographql.com/docs/apollo-server/integrations/plugins/#willsendresponse) lifecycle event. We can leverage it to clean up the container after handling the request. + +Example using `TypeDI` and `@apollo/server` with plugins approach: + +```ts +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { Container } from "typedi"; + +const server = new ApolloServer({ + // GraphQL schema + schema, + // Create a plugin to allow for disposing the scoped container created for every request + plugins: [ + { + requestDidStart: async () => ({ + async willSendResponse(requestContext) { + // Dispose the scoped container to prevent memory leaks + Container.reset(requestContext.contextValue.requestId.toString()); + + // For developers curiosity purpose, here is the logging of current scoped container instances + // Make multiple parallel requests to see in console how this works + const instancesIds = ((Container as any).instances as ContainerInstance[]).map( + instance => instance.id, + ); + console.log("Instances left in memory: ", instancesIds); + }, + }), + }, + ], +}); +``` + +And basically that's it! The configuration of the container is done and TypeGraphQL will be able to use different instances of resolvers for each request. + +The only thing that's left is the container configuration - we need to check out the docs for our container library (`InversifyJS`, `injection-js`, `TypeDI` or other) to get know how to setup the lifetime of the injectable objects (transient, scoped or singleton). + +> Be aware that some libraries (like `TypeDI`) by default create new instances for every scoped container, so you might experience a **significant increase in memory usage** and some slowing down in query resolving speed, so please be careful with using this feature! + +## Example + +You can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/using-container). + +For a more advanced usage example with scoped containers, check out [advanced example with scoped containers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/using-scoped-container). + +Integration with [TSyringe](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/tsyringe). diff --git a/website/versioned_docs/version-2.0.0-beta.4/directives.md b/website/versioned_docs/version-2.0.0-beta.4/directives.md new file mode 100644 index 000000000..15e2bc3e8 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.4/directives.md @@ -0,0 +1,163 @@ +--- +title: Directives +id: version-2.0.0-beta.4-directives +original_id: directives +--- + +> A directive is an identifier preceded by a `@` character, optionally followed by a list of named arguments, which can appear after almost any form of syntax in the GraphQL query or schema languages. + +Though the [GraphQL directives](https://www.apollographql.com/docs/graphql-tools/schema-directives) syntax is similar to TS decorators, they are purely an SDL (Schema Definition Language) feature that allows you to add metadata to a selected type or its field: + +```graphql +type Foo @auth(requires: USER) { + field: String! +} + +type Bar { + field: String! @auth(requires: USER) +} +``` + +That metadata can be read at runtime to modify the structure and behavior of a GraphQL schema to support reusable code and tasks like authentication, permission, formatting, and plenty more. They are also really useful for some external services like [Apollo Cache Control](https://www.apollographql.com/docs/apollo-server/performance/caching/#adding-cache-hints-statically-in-your-schema) or [Apollo Federation](https://www.apollographql.com/docs/apollo-server/federation/introduction/#federated-schema-example). + +**TypeGraphQL** of course provides some basic support for using the schema directives via the `@Directive` decorator. + +## Usage + +### Declaring in schema + +Basically, we declare the usage of directives just like in SDL, with the `@` syntax: + +```ts +@Directive('@deprecated(reason: "Use newField")') +``` + +Currently, you can use the directives only on object types, input types, interface types and their fields or fields resolvers, args type fields, as well as queries, mutations and subscriptions and the inline arguments. Other locations like scalars, enums or unions are not yet supported. + +So the `@Directive` decorator can be placed over the class property/method or over the type class itself, depending on the needs and the placements supported by the implementation: + +```ts +@Directive("@auth(requires: USER)") +@ObjectType() +class Foo { + @Field() + field: string; +} + +@ObjectType() +class Bar { + @Directive("@auth(requires: USER)") + @Field() + field: string; +} + +@ArgsType() +class FooBarArgs { + @Directive('@deprecated(reason: "Not used anymore")') + @Field({ nullable: true }) + baz?: string; +} + +@Resolver(of => Foo) +class FooBarResolver { + @Directive("@auth(requires: ANY)") + @Query() + foobar(@Args() { baz }: FooBarArgs): string { + return "foobar"; + } + + @Directive("@auth(requires: ADMIN)") + @FieldResolver() + bar(): string { + return "foobar"; + } +} +``` + +In case of inline args using `@Arg` decorator, directives can be placed over the parameter of the class method: + +```ts +@Resolver(of => Foo) +class FooBarResolver { + @Query() + foo( + @Directive('@deprecated(reason: "Not used anymore")') + @Arg("foobar", { defaultValue: "foobar" }) + foobar: string, + ) { + return "foo"; + } + + @FieldResolver() + bar( + @Directive('@deprecated(reason: "Not used anymore")') + @Arg("foobar", { defaultValue: "foobar" }) + foobar: string, + ) { + return "bar"; + } +} +``` + +> Note that even as directives are a purely SDL thing, they won't appear in the generated schema definition file. Current implementation of directives in TypeGraphQL is using some crazy workarounds because [`graphql-js` doesn't support setting them by code](https://github.com/graphql/graphql-js/issues/1343) and the built-in `printSchema` utility omits the directives while printing. See [emit schema with custom directives](./emit-schema.md#emit-schema-with-custom-directives) for more info. + +Also please note that `@Directive` can only contain a single GraphQL directive name or declaration. If you need to have multiple directives declared, just place multiple decorators: + +```ts +@ObjectType() +class Foo { + @Directive("@lowercase") + @Directive('@deprecated(reason: "Use `newField`")') + @Directive("@hasRole(role: Manager)") + @Field() + bar: string; +} +``` + +### Providing the implementation + +Besides declaring the usage of directives, you also have to register the runtime part of the used directives. + +> Be aware that TypeGraphQL doesn't have any special way for implementing schema directives. You should use some [3rd party libraries](https://the-guild.dev/graphql/tools/docs/schema-directives#implementing-schema-directives) depending on the tool set you use in your project, e.g. `@graphql-tools/*` or `ApolloServer`. + +If you write your custom GraphQL directive or import a package that exports a `GraphQLDirective` instance, you need to register the directives definitions in the `buildSchema` options: + +```ts +// Build TypeGraphQL executable schema +const tempSchema = await buildSchema({ + resolvers: [SampleResolver], + // Register the directives definitions + directives: [myDirective], +}); +``` + +Then you need to apply the schema transformer for your directive, that implements the desired logic of your directive: + +```ts +// Transform and obtain the final schema +const schema = myDirectiveTransformer(tempSchema); +``` + +If the directive package used by you exports a string-based `typeDefs`, you need to add those typedefs to the schema and then apply directive transformer. + +Here is an example using the [`@graphql-tools/*`](https://the-guild.dev/graphql/tools): + +```ts +import { mergeSchemas } from "@graphql-tools/schema"; +import { renameDirective } from "fake-rename-directive-package"; + +// Build TypeGraphQL executable schema +const schemaSimple = await buildSchema({ + resolvers: [SampleResolver], +}); + +// Merge schema with sample directive type definitions +const schemaMerged = mergeSchemas({ + schemas: [schemaSimple], + // Register the directives definitions + typeDefs: [renameDirective.typeDefs], +}); + +// Transform and obtain the final schema +const schema = renameDirective.transformer(schemaMerged); +``` diff --git a/website/versioned_docs/version-2.0.0-beta.4/emit-schema.md b/website/versioned_docs/version-2.0.0-beta.4/emit-schema.md new file mode 100644 index 000000000..99699ae4d --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.4/emit-schema.md @@ -0,0 +1,66 @@ +--- +title: Emitting the schema SDL +id: version-2.0.0-beta.4-emit-schema +original_id: emit-schema +--- + +TypeGraphQL's main feature is creating the schema using only TypeScript classes and decorators. However, there might be a need for the schema to be printed into a `schema.graphql` file and there are plenty of reasons for that. Mainly, the schema SDL file is needed for GraphQL ecosystem tools that perform client-side queries autocompletion and validation. Some developers also may want to use it as a kind of snapshot for detecting schema regression or they just prefer to read the SDL file to explore the API instead of reading the complicated TypeGraphQL-based app code, navigating through the GraphiQL or GraphQL Playground. To accomplish this demand, TypeGraphQL allows you to create a schema definition file in two ways. + +The first one is to generate it automatically on every build of the schema - just pass `emitSchemaFile: true` to the `buildSchema` options in order to emit the `schema.graphql` in the root of the project's working directory. You can also manually specify the path and the file name where the schema definition should be written or even specify `PrintSchemaOptions` to configure the look and format of the schema definition. + +```ts +const schema = await buildSchema({ + resolvers: [ExampleResolver], + // Automatically create `schema.graphql` file with schema definition in project's working directory + emitSchemaFile: true, + // Or create the file with schema in selected path + emitSchemaFile: path.resolve(__dirname, "__snapshots__/schema/schema.graphql"), + // Or pass a config object + emitSchemaFile: { + path: __dirname + "/schema.graphql", + sortedSchema: false, // By default the printed schema is sorted alphabetically + }, +}); +``` + +The second way to emit the schema definition file is by doing it programmatically. We would use the `emitSchemaDefinitionFile` function (or it's sync version `emitSchemaDefinitionFileSync`) and pass in the path, along with the schema object. We can use this among others as part of a testing script that checks if the snapshot of the schema definition is correct or to automatically generate it on every file change during local development. + +```ts +import { emitSchemaDefinitionFile } from "type-graphql"; + +// ... +hypotheticalFileWatcher.watch("./src/**/*.{resolver,type,input,arg}.ts", async () => { + const schema = getSchemaNotFromBuildSchemaFunction(); + await emitSchemaDefinitionFile("/path/to/folder/schema.graphql", schema); +}); +``` + +### Emit schema with custom directives + +Currently TypeGraphQL does not directly support emitting the schema with custom directives due to `printSchema` function limitations from `graphql-js`. + +If we want the custom directives to appear in the generated schema definition file we have to create a custom function that use a third-party `printSchema` function. + +Below there is an example that uses the `printSchemaWithDirectives` function from [`@graphql-tools/utils`](https://www.graphql-tools.com/docs/api/modules/utils): + +```ts +import { GraphQLSchema, lexicographicSortSchema } from "graphql"; +import { printSchemaWithDirectives } from "@graphql-tools/utils"; +import fs from "node:fs/promises"; + +export async function emitSchemaDefinitionWithDirectivesFile( + schemaFilePath: string, + schema: GraphQLSchema, +): Promise { + const schemaFileContent = printSchemaWithDirectives(lexicographicSortSchema(schema)); + await fs.writeFile(schemaFilePath, schemaFileContent); +} +``` + +The usage of `emitSchemaDefinitionWithDirectivesFile` function is the same as with standard `emitSchemaDefinitionFile`: + +```ts +const schema = await buildSchema(/*...*/); + +await emitSchemaDefinitionWithDirectivesFile("/path/to/folder/schema.graphql", schema); +``` diff --git a/website/versioned_docs/version-2.0.0-beta.4/esm.md b/website/versioned_docs/version-2.0.0-beta.4/esm.md new file mode 100644 index 000000000..a9db64bd2 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.4/esm.md @@ -0,0 +1,48 @@ +--- +title: ECMAScript Modules +id: version-2.0.0-beta.4-esm +original_id: esm +--- + +Since `v2.0.0` release, TypeGraphQL is compatible with ECMAScript modules. + +Thanks to this, we can `import` the `type-graphql` package in the ESM projects without any hassle. + +## TypeScript configuration + +It's important to properly configure the project, so that it uses ESM correctly: + +- the `module` option should be set to `NodeNext` +- the `moduleResolution` option should be set to `"NodeNext"` + +All in all, the `tsconfig.json` file should looks like this: + +```json title="tsconfig.json" +{ + "compilerOptions": { + "target": "es2021", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "experimentalDecorators": true, + "emitDecoratorMetadata": true + } +} +``` + +## Package.json configuration + +It is also important to set `type` option to `"module"` in your `package.json` file: + +```json title="package.json" +{ + "type": "module" +} +``` + +## Imports + +Apart from using `import` syntax, your local imports have to use the `.js` suffix, e.g.: + +```ts +import { MyResolver } from "./resolvers/MyResolver.js"; +``` diff --git a/website/versioned_docs/version-2.0.0-beta.4/examples.md b/website/versioned_docs/version-2.0.0-beta.4/examples.md new file mode 100644 index 000000000..7142d86b8 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.4/examples.md @@ -0,0 +1,53 @@ +--- +title: Examples +sidebar_label: List of examples +id: version-2.0.0-beta.4-examples +original_id: examples +--- + +On the [GitHub repository](https://github.com/MichalLytek/type-graphql) there are a few simple [`examples`](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples) of how to use different `TypeGraphQL` features and how well they integrate with 3rd party libraries. + +To run an example, simply go to the subdirectory (e.g. `cd ./simple-usage`), and then start the server (`npx ts-node ./index.ts`). + +Each subdirectory contains a `examples.graphql` file with predefined GraphQL queries/mutations/subscriptions that you can use in Apollo Studio () and play with them by modifying their shape and data. + +## Basics + +- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/simple-usage) + +## Advanced + +- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/enums-and-unions) +- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/simple-subscriptions) +- [Subscriptions (using Redis) \*\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/redis-subscriptions) +- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/interfaces-inheritance) +- [Extensions (metadata)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/extensions) + +## Features usage + +- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/using-container) + - [Scoped containers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/using-scoped-container) +- [Authorization](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/authorization) +- [Validation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/automatic-validation) + - [Custom validation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/custom-validation) +- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/interfaces-inheritance) +- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/resolvers-inheritance) +- [Generic types](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/generic-types) +- [Mixin classes](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/mixin-classes) +- [Middlewares and Custom Decorators](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/middlewares-custom-decorators) +- [Query complexity](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/query-complexity) + +## 3rd party libs integration + +- [TypeORM (manual, synchronous) \*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/typeorm-basic-usage) +- [TypeORM (automatic, lazy relations) \*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/typeorm-lazy-relations) +- [MikroORM \*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/mikro-orm) +- [Typegoose \*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/typegoose) +- [Apollo Federation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/apollo-federation) +- [Apollo Federation 2](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/apollo-federation-2) +- [Apollo Cache Control](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/apollo-cache) +- [GraphQL Scalars](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/graphql-scalars) +- [TSyringe](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/tsyringe) + +_\* Note that we need to provide the environment variable `DATABASE_URL` with connection parameters to your local database_ \ +_\*\* Note that we need to provide the environment variable `REDIS_URL` with connection parameters to your local Redis instance_ diff --git a/website/versioned_docs/version-2.0.0-beta.4/extensions.md b/website/versioned_docs/version-2.0.0-beta.4/extensions.md new file mode 100644 index 000000000..98f10bea7 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.4/extensions.md @@ -0,0 +1,119 @@ +--- +title: Extensions +id: version-2.0.0-beta.4-extensions +original_id: extensions +--- + +The `graphql-js` library allows for putting arbitrary data into GraphQL types config inside the `extensions` property. +Annotating schema types or fields with a custom metadata, that can be then used at runtime by middlewares or resolvers, is a really powerful and useful feature. + +For such use cases, **TypeGraphQL** provides the `@Extensions` decorator, which adds the data we defined to the `extensions` property of the executable schema for the decorated classes, methods or properties. + +> Be aware that this is a low-level decorator and you generally have to provide your own logic to make use of the `extensions` metadata. + +## Using the `@Extensions` decorator + +Adding extensions to the schema type is as simple as using the `@Extensions` decorator and passing it an object of the custom data we want: + +```ts +@Extensions({ complexity: 2 }) +``` + +We can pass several fields to the decorator: + +```ts +@Extensions({ logMessage: "Restricted access", logLevel: 1 }) +``` + +And we can also decorate a type several times. The snippet below shows that this attaches the exact same extensions data to the schema type as the snippet above: + +```ts +@Extensions({ logMessage: "Restricted access" }) +@Extensions({ logLevel: 1 }) +``` + +If we decorate the same type several times with the same extensions key, the one defined at the bottom takes precedence: + +```ts +@Extensions({ logMessage: "Restricted access" }) +@Extensions({ logMessage: "Another message" }) +``` + +The above usage results in your GraphQL type having a `logMessage: "Another message"` property in its extensions. + +TypeGraphQL classes with the following decorators can be annotated with `@Extensions` decorator: + +- `@ObjectType` +- `@InputType` +- `@Field` +- `@Query` +- `@Mutation` +- `@FieldResolver` + +So the `@Extensions` decorator can be placed over the class property/method or over the type class itself, and multiple times if necessary, depending on what we want to do with the extensions data: + +```ts +@Extensions({ roles: ["USER"] }) +@ObjectType() +class Foo { + @Field() + field: string; +} + +@ObjectType() +class Bar { + @Extensions({ roles: ["USER"] }) + @Field() + field: string; +} + +@ObjectType() +class Bar { + @Extensions({ roles: ["USER"] }) + @Extensions({ visible: false, logMessage: "User accessed restricted field" }) + @Field() + field: string; +} + +@Resolver(of => Foo) +class FooBarResolver { + @Extensions({ roles: ["USER"] }) + @Query() + foobar(@Arg("baz") baz: string): string { + return "foobar"; + } + + @Extensions({ roles: ["ADMIN"] }) + @FieldResolver() + bar(): string { + return "foobar"; + } +} +``` + +## Using the extensions data in runtime + +Once we have decorated the necessary types with extensions, the executable schema will contain the extensions data, and we can make use of it in any way we choose. The most common use will be to read it at runtime in resolvers or middlewares and perform some custom logic there. + +Here is a simple example of a global middleware that will be logging a message on field resolver execution whenever the field is decorated appropriately with `@Extensions`: + +```ts +export class LoggerMiddleware implements MiddlewareInterface { + constructor(private readonly logger: Logger) {} + + use({ info }: ResolverData, next: NextFn) { + // extract `extensions` object from GraphQLResolveInfo object to get the `logMessage` value + const { logMessage } = info.parentType.getFields()[info.fieldName].extensions || {}; + + if (logMessage) { + this.logger.log(logMessage); + } + + return next(); + } +} +``` + +## Examples + +You can see more detailed examples of usage [here](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/extensions). diff --git a/website/versioned_docs/version-2.0.0-beta.4/generic-types.md b/website/versioned_docs/version-2.0.0-beta.4/generic-types.md new file mode 100644 index 000000000..1fc0b0012 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.4/generic-types.md @@ -0,0 +1,169 @@ +--- +title: Generic Types +id: version-2.0.0-beta.4-generic-types +original_id: generic-types +--- + +[Type Inheritance](./inheritance.md) is a great way to reduce code duplication by extracting common fields to the base class. But in some cases, the strict set of fields is not enough because we might need to declare the types of some fields in a more flexible way, like a type parameter (e.g. `items: T[]` in case of a pagination). + +Hence TypeGraphQL also has support for describing generic GraphQL types. + +## How to? + +Unfortunately, the limited reflection capabilities of TypeScript don't allow for combining decorators with standard generic classes. To achieve behavior like that of generic types, we use the same class-creator pattern like the one described in the [Resolvers Inheritance](./inheritance.md) docs. + +### Basic usage + +Start by defining a `PaginatedResponse` function that creates and returns an abstract `PaginatedResponseClass`: + +```ts +export default function PaginatedResponse() { + abstract class PaginatedResponseClass { + // ... + } + return PaginatedResponseClass; +} +``` + +To achieve generic-like behavior, the function has to be generic and take some runtime argument related to the type parameter: + +```ts +export default function PaginatedResponse(TItemClass: ClassType) { + abstract class PaginatedResponseClass { + // ... + } + return PaginatedResponseClass; +} +``` + +Then, add proper decorators to the class which might be `@ObjectType`, `@InterfaceType` or `@InputType`: + +```ts +export default function PaginatedResponse(TItemClass: ClassType) { + @ObjectType() + abstract class PaginatedResponseClass { + // ... + } + return PaginatedResponseClass; +} +``` + +After that, add fields like in a normal class but using the generic type and parameters: + +```ts +export default function PaginatedResponse(TItemClass: ClassType) { + @ObjectType() + abstract class PaginatedResponseClass { + // Runtime argument + @Field(type => [TItemClass]) + // Generic type + items: TItem[]; + + @Field(type => Int) + total: number; + + @Field() + hasMore: boolean; + } + return PaginatedResponseClass; +} +``` + +Finally, use the generic function factory to create a dedicated type class: + +```ts +@ObjectType() +class PaginatedUserResponse extends PaginatedResponse(User) { + // Add more fields or overwrite the existing one's types + @Field(type => [String]) + otherInfo: string[]; +} +``` + +And then use it in our resolvers: + +```ts +@Resolver() +class UserResolver { + @Query() + users(): PaginatedUserResponse { + // Custom business logic, + // depending on underlying data source and libraries + return { + items, + total, + hasMore, + otherInfo, + }; + } +} +``` + +### Complex generic type values + +When we need to provide something different than a class (object type) for the field type, we need to enhance the parameter type signature and provide the needed types. + +Basically, the parameter that the `PaginatedResponse` function accepts is the value we can provide to `@Field` decorator. +So if we want to return an array of strings as the `items` field, we need to add proper types to the function signature, like `GraphQLScalarType` or `String`: + +```ts +export default function PaginatedResponse( + itemsFieldValue: ClassType | GraphQLScalarType | String | Number | Boolean, +) { + @ObjectType() + abstract class PaginatedResponseClass { + @Field(type => [itemsFieldValue]) + items: TItemsFieldValue[]; + + // ... Other fields + } + return PaginatedResponseClass; +} +``` + +And then provide a proper runtime value (like `String`) while creating a proper subtype of generic `PaginatedResponse` object type: + +```ts +@ObjectType() +class PaginatedStringsResponse extends PaginatedResponse(String) { + // ... +} +``` + +### Types factory + +We can also create a generic class without using the `abstract` keyword. +But with this approach, types created with this kind of factory will be registered in the schema, so this way is not recommended to extend the types for adding fields. + +To avoid generating schema errors of duplicated `PaginatedResponseClass` type names, we must provide our own unique, generated type name: + +```ts +export default function PaginatedResponse(TItemClass: ClassType) { + // Provide a unique type name used in schema + @ObjectType(`Paginated${TItemClass.name}Response`) + class PaginatedResponseClass { + // ... + } + return PaginatedResponseClass; +} +``` + +Then, we can store the generated class in a variable and in order to use it both as a runtime object and as a type, we must also create a type for this new class: + +```ts +const PaginatedUserResponse = PaginatedResponse(User); +type PaginatedUserResponse = InstanceType; + +@Resolver() +class UserResolver { + // Provide a runtime type argument to the decorator + @Query(returns => PaginatedUserResponse) + users(): PaginatedUserResponse { + // Same implementation as in the earlier code snippet + } +} +``` + +## Examples + +A more advanced usage example of the generic types feature can be found in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/generic-types). diff --git a/website/versioned_docs/version-2.0.0-beta.4/inheritance.md b/website/versioned_docs/version-2.0.0-beta.4/inheritance.md new file mode 100644 index 000000000..963781d51 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.4/inheritance.md @@ -0,0 +1,145 @@ +--- +title: Inheritance +id: version-2.0.0-beta.4-inheritance +original_id: inheritance +--- + +The main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes. + +In object-oriented programming it is common to compose classes using inheritance. Hence, TypeGraphQL supports composing type definitions by extending classes. + +## Types inheritance + +One of the most known principles of software development is DRY - Don't Repeat Yourself - which is about avoiding code redundancy. + +While creating a GraphQL API, it's a common pattern to have pagination args in resolvers, like `skip` and `take`. So instead of repeating ourselves, we declare it once: + +```ts +@ArgsType() +class PaginationArgs { + @Field(type => Int) + skip: number = 0; + + @Field(type => Int) + take: number = 25; +} +``` + +and then reuse it everywhere: + +```ts +@ArgsType() +class GetTodosArgs extends PaginationArgs { + @Field() + onlyCompleted: boolean = false; +} +``` + +This technique also works with input type classes, as well as with object type classes: + +```ts +@ObjectType() +class Person { + @Field() + age: number; +} + +@ObjectType() +class Student extends Person { + @Field() + universityName: string; +} +``` + +Note that both the subclass and the parent class must be decorated with the same type of decorator, like `@ObjectType()` in the example `Person -> Student` above. Mixing decorator types across parent and child classes is prohibited and might result in a schema building error, e.g. we can't decorate the subclass with `@ObjectType()` and the parent with `@InputType()`. + +## Resolver Inheritance + +A special kind of inheritance in TypeGraphQL is resolver class inheritance. This pattern allows us e.g. to create a base CRUD resolver class for our resource/entity, so we don't have to repeat common boilerplate code. + +Since we need to generate unique query/mutation names, we have to create a factory function for our base class: + +```ts +function createBaseResolver() { + abstract class BaseResolver {} + + return BaseResolver; +} +``` + +Be aware that with some `tsconfig.json` settings (like `declarations: true`) we might receive a `[ts] Return type of exported function has or is using private name 'BaseResolver'` error - in this case we might need to use `any` as the return type or create a separate class/interface describing the class methods and properties. + +This factory should take a parameter that we can use to generate the query/mutation names, as well as the type that we would return from the resolvers: + +```ts +function createBaseResolver(suffix: string, objectTypeCls: T) { + abstract class BaseResolver {} + + return BaseResolver; +} +``` + +It's very important to mark the `BaseResolver` class using the `@Resolver` decorator: + +```ts +function createBaseResolver(suffix: string, objectTypeCls: T) { + @Resolver() + abstract class BaseResolver {} + + return BaseResolver; +} +``` + +We can then implement the resolver methods as usual. The only difference is that we can use the `name` decorator option for `@Query`, `@Mutation` and `@Subscription` decorators to overwrite the name that will be emitted in schema: + +```ts +function createBaseResolver(suffix: string, objectTypeCls: T) { + @Resolver() + abstract class BaseResolver { + protected items: T[] = []; + + @Query(type => [objectTypeCls], { name: `getAll${suffix}` }) + async getAll(@Arg("first", type => Int) first: number): Promise { + return this.items.slice(0, first); + } + } + + return BaseResolver; +} +``` + +Now we can create a specific resolver class that will extend the base resolver class: + +```ts +const PersonBaseResolver = createBaseResolver("person", Person); + +@Resolver(of => Person) +export class PersonResolver extends PersonBaseResolver { + // ... +} +``` + +We can also add specific queries and mutations in our resolver class, as always: + +```ts +const PersonBaseResolver = createBaseResolver("person", Person); + +@Resolver(of => Person) +export class PersonResolver extends PersonBaseResolver { + @Mutation() + addPerson(@Arg("input") personInput: PersonInput): Person { + this.items.push(personInput); + return personInput; + } +} +``` + +And that's it! We just need to normally register `PersonResolver` in `buildSchema` and the extended resolver will work correctly. + +We must be aware that if we want to overwrite the query/mutation/subscription from the parent resolver class, we need to generate the same schema name (using the `name` decorator option or the class method name). It will overwrite the implementation along with the GraphQL args and return types. If we only provide a different implementation of the inherited method like `getOne`, it won't work. + +## Examples + +More advanced usage examples of type inheritance (and interfaces) can be found in [the example folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/interfaces-inheritance). + +For a more advanced resolver inheritance example, please go to [this example folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/resolvers-inheritance). diff --git a/website/versioned_docs/version-2.0.0-beta.4/interfaces.md b/website/versioned_docs/version-2.0.0-beta.4/interfaces.md new file mode 100644 index 000000000..60a912876 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.4/interfaces.md @@ -0,0 +1,258 @@ +--- +title: Interfaces +id: version-2.0.0-beta.4-interfaces +original_id: interfaces +--- + +The main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes. + +In object-oriented programming it is common to create interfaces which describe the contract that classes implementing them must adhere to. Hence, TypeGraphQL supports defining GraphQL interfaces. + +Read more about the GraphQL Interface Type in the [official GraphQL docs](https://graphql.org/learn/schema/#interfaces). + +## Abstract classes + +TypeScript has first class support for interfaces. Unfortunately, they only exist at compile-time, so we can't use them to build GraphQL schema at runtime by using decorators. + +Luckily, we can use an abstract class for this purpose. It behaves almost like an interface as it can't be instantiated but it can be implemented by another class. The only difference is that it just won't prevent developers from implementing a method or initializing a field. So, as long as we treat the abstract class like an interface, we can safely use it. + +## Defining interface type + +How do we create a GraphQL interface definition? We create an abstract class and decorate it with the `@InterfaceType()` decorator. The rest is exactly the same as with object types: we use the `@Field` decorator to declare the shape of the type: + +```ts +@InterfaceType() +abstract class IPerson { + @Field(type => ID) + id: string; + + @Field() + name: string; + + @Field(type => Int) + age: number; +} +``` + +We can then use this interface type class like an interface in the object type class definition: + +```ts +@ObjectType({ implements: IPerson }) +class Person implements IPerson { + id: string; + name: string; + age: number; +} +``` + +The only difference is that we have to let TypeGraphQL know that this `ObjectType` is implementing the `InterfaceType`. We do this by passing the param `({ implements: IPerson })` to the decorator. If we implement multiple interfaces, we pass an array of interfaces like so: `({ implements: [IPerson, IAnimal, IMachine] })`. + +It is also allowed to omit the decorators since the GraphQL types will be copied from the interface definition - this way we won't have to maintain two definitions and solely rely on TypeScript type checking for correct interface implementation. + +We can also extend the base interface type abstract class as well because all the fields are inherited and emitted in schema: + +```ts +@ObjectType({ implements: IPerson }) +class Person extends IPerson { + @Field() + hasKids: boolean; +} +``` + +## Implementing other interfaces + +Since `graphql-js` version `15.0`, it's also possible for interface type to [implement other interface types](https://github.com/graphql/graphql-js/pull/2084). + +To accomplish this, we can just use the same syntax that we utilize for object types - the `implements` decorator option: + +```ts +@InterfaceType() +class Node { + @Field(type => ID) + id: string; +} + +@InterfaceType({ implements: Node }) +class Person extends Node { + @Field() + name: string; + + @Field(type => Int) + age: number; +} +``` + +Also, when we implement the interface that already implements other interface, there's no need to put them all in `implements` array in `@ObjectType` decorator option - only the closest one in the inheritance chain is required, e.g.: + +```ts +@ObjectType({ implements: [Person] }) +class Student extends Person { + @Field() + universityName: string; +} +``` + +This example produces following representation in GraphQL SDL: + +```graphql +interface Node { + id: ID! +} + +interface Person implements Node { + id: ID! + name: String! + age: Int! +} + +type Student implements Node & Person { + id: ID! + name: String! + age: Int! + universityName: String! +} +``` + +## Resolvers and arguments + +What's more, we can define resolvers for the interface fields, using the same syntax we would use when defining one for our object type: + +```ts +@InterfaceType() +abstract class IPerson { + @Field() + firstName: string; + + @Field() + lastName: string; + + @Field() + fullName(): string { + return `${this.firstName} ${this.lastName}`; + } +} +``` + +They're inherited by all the object types that implements this interface type but does not provide their own resolver implementation for those fields. + +Additionally, if we want to declare that the interface accepts some arguments, e.g.: + +```graphql +interface IPerson { + avatar(size: Int!): String! +} +``` + +We can just use `@Arg` or `@Args` decorators as usual: + +```ts +@InterfaceType() +abstract class IPerson { + @Field() + avatar(@Arg("size") size: number): string { + return `http://i.pravatar.cc/${size}`; + } +} +``` + +Unfortunately, TypeScript doesn't allow using decorators on abstract methods. +So if we don't want to provide implementation for that field resolver, only to enforce some signature (args and return type), we have to throw an error inside the body: + +```ts +@InterfaceType() +abstract class IPerson { + @Field() + avatar(@Arg("size") size: number): string { + throw new Error("Method not implemented!"); + } +} +``` + +And then we need to extend the interface class and override the method by providing its body - it is required for all object types that implements that interface type: + +```ts +@ObjectType({ implements: IPerson }) +class Person extends IPerson { + avatar(size: number): string { + return `http://i.pravatar.cc/${size}`; + } +} +``` + +In order to extend the signature by providing additional arguments (like `format`), we need to redeclare the whole field signature: + +```ts +@ObjectType({ implements: IPerson }) +class Person implements IPerson { + @Field() + avatar(@Arg("size") size: number, @Arg("format") format: string): string { + return `http://i.pravatar.cc/${size}.${format}`; + } +} +``` + +Resolvers for interface type fields can be also defined on resolvers classes level, by using the `@FieldResolver` decorator: + +```ts +@Resolver(of => IPerson) +class IPersonResolver { + @FieldResolver() + avatar(@Root() person: IPerson, @Arg("size") size: number): string { + return `http://typegraphql.com/${person.id}/${size}`; + } +} +``` + +## Registering in schema + +By default, if the interface type is explicitly used in schema definition (used as a return type of a query/mutation or as some field type), all object types that implement that interface will be emitted in schema, so we don't need to do anything. + +However, in some cases like the `Node` interface that is used in Relay-based systems, this behavior might be not intended when exposing multiple, separates schemas (like a public and the private ones). + +In this situation, we can provide an `{ autoRegisterImplementations: false }` option to the `@InterfaceType` decorator to prevent emitting all this object types in the schema: + +```ts +@InterfaceType({ autoRegisterImplementations: false }) +abstract class Node { + @Field(type => ID) + id: string; +} +``` + +Then we need to add all the object types (that implement this interface type and which we want to expose in selected schema) to the `orphanedTypes` array option in `buildSchema`: + +```ts +const schema = await buildSchema({ + resolvers, + // Provide orphaned object types + orphanedTypes: [Person, Animal, Recipe], +}); +``` + +Be aware that if the object type class is explicitly used as the GraphQL type (like `Recipe` type as the return type of `addRecipe` mutation), it will be emitted regardless the `orphanedTypes` setting. + +## Resolving Type + +Be aware that when our object type is implementing a GraphQL interface type, **we have to return an instance of the type class** in our resolvers. Otherwise, `graphql-js` will not be able to detect the underlying GraphQL type correctly. + +We can also provide our own `resolveType` function implementation to the `@InterfaceType` options. This way we can return plain objects in resolvers and then determine the returned object type by checking the shape of the data object, the same ways [like in unions](./unions.md), e.g.: + +```ts +@InterfaceType({ + resolveType: value => { + if ("grades" in value) { + return "Student"; // Schema name of type string + } + return Person; // Or object type class + }, +}) +abstract class IPerson { + // ... +} +``` + +However in case of interfaces, it might be a little bit more tricky than with unions, as we might not remember all the object types that implements this particular interface. + +## Examples + +For more advanced usage examples of interfaces (and type inheritance), e.g. with query returning an interface type, go to [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/interfaces-inheritance). diff --git a/website/versioned_docs/version-2.0.0-beta.4/middlewares.md b/website/versioned_docs/version-2.0.0-beta.4/middlewares.md new file mode 100644 index 000000000..1ad0ad9d1 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.4/middlewares.md @@ -0,0 +1,189 @@ +--- +title: Middleware and guards +id: version-2.0.0-beta.4-middlewares +original_id: middlewares +--- + +Middleware are pieces of reusable code that can be easily attached to resolvers and fields. By using middleware we can extract the commonly used code from our resolvers and then declaratively attach it using a decorator or even registering it globally. + +## Creating Middleware + +### What is Middleware? + +Middleware is a very powerful but somewhat complicated feature. Basically, middleware is a function that takes 2 arguments: + +- resolver data - the same as resolvers (`root`, `args`, `context`, `info`) +- the `next` function - used to control the execution of the next middleware and the resolver to which it is attached + +We may be familiar with how middleware works in [`express.js`](https://expressjs.com/en/guide/writing-middleware.html) but TypeGraphQL middleware is inspired by [`koa.js`](http://koajs.com/#application). The difference is that the `next` function returns a promise of the value of subsequent middleware and resolver execution from the stack. + +This makes it easy to perform actions before or after resolver execution. So things like measuring execution time are simple to implement: + +```ts +export const ResolveTime: MiddlewareFn = async ({ info }, next) => { + const start = Date.now(); + await next(); + const resolveTime = Date.now() - start; + console.log(`${info.parentType.name}.${info.fieldName} [${resolveTime} ms]`); +}; +``` + +### Intercepting the execution result + +Middleware also has the ability to intercept the result of a resolver's execution. It's not only able to e.g. create a log but also replace the result with a new value: + +```ts +export const CompetitorInterceptor: MiddlewareFn = async (_, next) => { + const result = await next(); + if (result === "typegql") { + return "type-graphql"; + } + return result; +}; +``` + +It might not seem very useful from the perspective of this library's users but this feature was mainly introduced for plugin systems and 3rd-party library integration. Thanks to this, it's possible to e.g. wrap the returned object with a lazy-relation wrapper that automatically fetches relations from a database on demand under the hood. + +### Simple Middleware + +If we only want to do something before an action, like log the access to the resolver, we can just place the `return next()` statement at the end of our middleware: + +```ts +const LogAccess: MiddlewareFn = ({ context, info }, next) => { + const username: string = context.username || "guest"; + console.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`); + return next(); +}; +``` + +### Guards + +Middleware can also break the middleware stack by not calling the `next` function. This way, the result returned from the middleware will be used instead of calling the resolver and returning it's result. + +We can also throw an error in the middleware if the execution must be terminated and an error returned to the user, e.g. when resolver arguments are incorrect. + +This way we can create a guard that blocks access to the resolver and prevents execution or any data return. + +```ts +export const CompetitorDetector: MiddlewareFn = async ({ args }, next) => { + if (args.frameworkName === "type-graphql") { + return "TypeGraphQL"; + } + if (args.frameworkName === "typegql") { + throw new Error("Competitive framework detected!"); + } + return next(); +}; +``` + +### Reusable Middleware + +Sometimes middleware has to be configurable, just like we pass a `roles` array to the [`@Authorized()` decorator](./authorization.md). In this case, we should create a simple middleware factory - a function that takes our configuration as a parameter and returns a middleware that uses the provided value. + +```ts +export function NumberInterceptor(minValue: number): MiddlewareFn { + return async (_, next) => { + const result = await next(); + // Hide values below minValue + if (typeof result === "number" && result < minValue) { + return null; + } + return result; + }; +} +``` + +Remember to call this middleware with an argument, e.g. `NumberInterceptor(3.0)`, when attaching it to a resolver! + +### Error Interceptors + +Middleware can also catch errors that were thrown during execution. This way, they can easily be logged and even filtered for info that can't be returned to the user: + +```ts +export const ErrorInterceptor: MiddlewareFn = async ({ context, info }, next) => { + try { + return await next(); + } catch (err) { + // Write error to file log + fileLog.write(err, context, info); + + // Hide errors from db like printing sql query + if (someCondition(err)) { + throw new Error("Unknown error occurred!"); + } + + // Rethrow the error + throw err; + } +}; +``` + +### Class-based Middleware + +Sometimes our middleware logic can be a bit complicated - it may communicate with a database, write logs to file, etc., so we might want to test it. In that case we create class middleware that is able to benefit from [dependency injection](./dependency-injection.md) and easily mock a file logger or a database repository. + +To accomplish this, we implement a `MiddlewareInterface`. Our class must have the `use` method that conforms with the `MiddlewareFn` signature. Below we can see how the previously defined `LogAccess` middleware looks after the transformation: + +```ts +export class LogAccess implements MiddlewareInterface { + constructor(private readonly logger: Logger) {} + + async use({ context, info }: ResolverData, next: NextFn) { + const username: string = context.username || "guest"; + this.logger.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`); + return next(); + } +} +``` + +## How to use + +### Attaching Middleware + +To attach middleware to a resolver, place the `@UseMiddleware()` decorator above the field or resolver declaration. It accepts an array of middleware that will be called in the provided order. We can also pass them without an array as it supports [rest parameters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters): + +```ts +@Resolver() +export class RecipeResolver { + @Query() + @UseMiddleware(ResolveTime, LogAccess) + randomValue(): number { + return Math.random(); + } +} +``` + +We can also attach the middleware to the `ObjectType` fields, the same way as with the [`@Authorized()` decorator](./authorization.md). + +```ts +@ObjectType() +export class Recipe { + @Field() + title: string; + + @Field(type => [Int]) + @UseMiddleware(LogAccess) + ratings: number[]; +} +``` + +### Global Middleware + +However, for common middleware like measuring resolve time or catching errors, it might be annoying to place a `@UseMiddleware(ResolveTime)` decorator on every field/resolver. + +Hence, in TypeGraphQL we can also register a global middleware that will be called for each query, mutation, subscription and field resolver. For this, we use the `globalMiddlewares` property of the `buildSchema` configuration object: + +```ts +const schema = await buildSchema({ + resolvers: [RecipeResolver], + globalMiddlewares: [ErrorInterceptor, ResolveTime], +}); +``` + +### Custom Decorators + +If we want to use middlewares with a more descriptive and declarative API, we can also create a custom method decorators. See how to do this in [custom decorators docs](./custom-decorators.md#method-decorators). + +## Example + +See how different kinds of middlewares work in the [middlewares and custom decorators example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/middlewares-custom-decorators). diff --git a/website/versioned_docs/version-2.0.0-beta.4/migration-guide.md b/website/versioned_docs/version-2.0.0-beta.4/migration-guide.md new file mode 100644 index 000000000..0165196d7 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.4/migration-guide.md @@ -0,0 +1,71 @@ +--- +title: Migration Guide +sidebar_label: v1.x -> v2.0 +id: version-2.0.0-beta.4-migration-guide +original_id: migration-guide +--- + +> This chapter contains migration guide, that will help you upgrade your codebase from using old Typegraphql `v1.x` into the newest `v2.0` release. +> +> If you just started using TypeGraphQL and you have `v2.0` installed, you can skip this chapter and go straight into the "Advanced guides" section. + +## Subscriptions + +The new `v2.0` release contains a bunch of breaking changes related to the GraphQL subscriptions feature. + +In previous releases, this feature was build upon the [`graphql-subscriptions`](https://github.com/apollographql/graphql-subscriptions) package and it's `PubSub` system. +However, it's become unmaintained in the last years and some alternatives has been developed in the meantime. + +So since `v2.0`, TypeGraphQL relies on the new [`@graphql-yoga/subscriptions`](https://the-guild.dev/graphql/yoga-server/docs/features/subscriptions) package which is built on top of latest ECMAScript features. It also has own `PubSub` implementation which works in a similar fashion, but has a slightly different API. + +We did out best to hide under the hood all the differences between the APIs of those packages, but some breaking changes had to occurred in the TypeGraphQL API. + +### The `pubSub` option of `buildSchema` + +It is now required to pass the `PubSub` instance as the config option of `buildSchema` function. +Previously, you could omit it and rely on the default one created by TypeGraphQL. + +The reason for this change is that `@graphql-yoga/subscriptions` package allows to create a type-safe `PubSub` instance via the [generic `createPubSub` function](https://the-guild.dev/graphql/yoga-server/v2/features/subscriptions#topics), so you can add type info about the topics and params required while using `.publish()` method. + +Simple example of the new API: + +```ts +import { buildSchema } from "type-graphql"; +import { createPubSub } from "@graphql-yoga/subscriptions"; + +export const pubSub = createPubSub<{ + NOTIFICATIONS: [NotificationPayload]; + DYNAMIC_ID_TOPIC: [number, NotificationPayload]; +}>(); + +const schema = await buildSchema({ + resolver, + pubSub, +}); +``` + +Be aware that you can use any `PubSub` system you want, not only the `graphql-yoga` one. +The only requirement is to comply with the exported `PubSub` interface - having proper `.subscribe()` and `.publish()` methods. + +### No `@PubSub` decorator + +The consequence of not having automatically created, default `PubSub` instance, is that you don't need access to the internally-created `PubSub` instance. + +Hence, the `@PubSub` decorator was removed - please use dependency injection system if you don't want to have a hardcoded import. The corresponding `Publisher` type was also removed as it was not needed anymore. + +### Renamed and removed types + +There was some inconsistency in naming of the decorator option functions argument types, which was unified in the `v2.0` release. + +If you reference those types in your code (`filter` or `subscribe` decorator option functions), make sure you update your type annotation and imports to the new name. + +- `ResolverFilterData` -> `SubscriptionHandlerData` +- `ResolverTopicData` -> `SubscribeResolverData` + +Also, apart from the `Publisher` type mentioned above, the `PubSubEngine` type has been removed and is no longer exported from the package. + +### Topic with Dynamic ID + +As TypeGraphQL uses `@graphql-yoga/subscriptions` under the hood, it also aims to use its features. And one of the extension to the old `PubSub` system used in `v1.x` is ability to not only use dynamic topics but a topic with a dynamic id. + +You can read more about this new feature in [subscription docs](./subscriptions.md#topic-with-dynamic-id). diff --git a/website/versioned_docs/version-2.0.0-beta.4/resolvers.md b/website/versioned_docs/version-2.0.0-beta.4/resolvers.md new file mode 100644 index 000000000..45da37c00 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.4/resolvers.md @@ -0,0 +1,352 @@ +--- +title: Resolvers +id: version-2.0.0-beta.4-resolvers +original_id: resolvers +--- + +Besides [declaring GraphQL's object types](./types-and-fields.md), TypeGraphQL allows us to easily create queries, mutations and field resolvers - like normal class methods, similar to REST controllers in frameworks like Java `Spring`, .NET `Web API` or TypeScript [`routing-controllers`](https://github.com/typestack/routing-controllers). + +## Queries and Mutations + +### Resolver classes + +First we create the resolver class and annotate it with the `@Resolver()` decorator. This class will behave like a controller from classic REST frameworks: + +```ts +@Resolver() +class RecipeResolver {} +``` + +We can use a DI framework (as described in the [dependency injection docs](./dependency-injection.md)) to inject class dependencies (like services or repositories) or to store data inside the resolver class - it's guaranteed to be a single instance per app. + +```ts +@Resolver() +class RecipeResolver { + private recipesCollection: Recipe[] = []; +} +``` + +Then we can create class methods which will handle queries and mutations. For example, let's add the `recipes` query to return a collection of all recipes: + +```ts +@Resolver() +class RecipeResolver { + private recipesCollection: Recipe[] = []; + + async recipes() { + // Fake async + return await this.recipesCollection; + } +} +``` + +We also need to do two things. +The first is to add the `@Query` decorator, which marks the class method as a GraphQL query. +The second is to provide the return type. Since the method is async, the reflection metadata system shows the return type as a `Promise`, so we have to add the decorator's parameter as `returns => [Recipe]` to declare it resolves to an array of `Recipe` object types. + +```ts +@Resolver() +class RecipeResolver { + private recipesCollection: Recipe[] = []; + + @Query(returns => [Recipe]) + async recipes() { + return await this.recipesCollection; + } +} +``` + +### Arguments + +Usually, queries have some arguments - it might be the id of a resource, a search phrase or pagination settings. TypeGraphQL allows you to define arguments in two ways. + +First is the inline method using the `@Arg()` decorator. The drawback is the need to repeating the argument name (due to a limitation of the reflection system) in the decorator parameter. As we can see below, we can also pass a `defaultValue` option that will be reflected in the GraphQL schema. + +```ts +@Resolver() +class RecipeResolver { + // ... + @Query(returns => [Recipe]) + async recipes( + @Arg("servings", { defaultValue: 2 }) servings: number, + @Arg("title", { nullable: true }) title?: string, + ): Promise { + // ... + } +} +``` + +This works well when there are 2 - 3 args. But when you have many more, the resolver's method definitions become bloated. In this case we can use a class definition to describe the arguments. It looks like the object type class but it has the `@ArgsType()` decorator on top. + +```ts +@ArgsType() +class GetRecipesArgs { + @Field(type => Int, { nullable: true }) + skip?: number; + + @Field(type => Int, { nullable: true }) + take?: number; + + @Field({ nullable: true }) + title?: string; +} +``` + +We can define default values for optional fields in the `@Field()` decorator using the `defaultValue` option or by using a property initializer - in both cases TypeGraphQL will reflect this in the schema by setting the default value, so users will be able to omit those args while sending a query. + +> Be aware that `defaultValue` works only for input args and fields, like `@Arg`, `@ArgsType` and `@InputType`. +> Setting `defaultValue` does not affect `@ObjectType` or `@InterfaceType` fields as they are for output purposes only. + +Also, this way of declaring arguments allows you to perform validation. You can find more details about this feature in the [validation docs](./validation.md). + +We can also define helper fields and methods for our args or input classes. But be aware that **defining constructors is strictly forbidden** and we shouldn't use them there, as TypeGraphQL creates instances of args and input classes under the hood by itself. + +```ts +import { Min, Max } from "class-validator"; + +@ArgsType() +class GetRecipesArgs { + @Field(type => Int, { defaultValue: 0 }) + @Min(0) + skip: number; + + @Field(type => Int) + @Min(1) + @Max(50) + take = 25; + + @Field({ nullable: true }) + title?: string; + + // Helpers - index calculations + get startIndex(): number { + return this.skip; + } + get endIndex(): number { + return this.skip + this.take; + } +} +``` + +Then all that is left to do is use the args class as the type of the method parameter. +We can use the destructuring syntax to gain access to single arguments as variables, instead of the reference to the whole args object. + +```ts +@Resolver() +class RecipeResolver { + // ... + @Query(returns => [Recipe]) + async recipes(@Args() { title, startIndex, endIndex }: GetRecipesArgs) { + // Example implementation + let recipes = this.recipesCollection; + if (title) { + recipes = recipes.filter(recipe => recipe.title === title); + } + return recipes.slice(startIndex, endIndex); + } +} +``` + +This declaration will result in the following part of the schema in SDL: + +```graphql +type Query { + recipes(skip: Int = 0, take: Int = 25, title: String): [Recipe!] +} +``` + +### Input types + +GraphQL mutations can be similarly created: Declare the class method, use the `@Mutation` decorator, create arguments, provide a return type (if needed) etc. But for mutations we usually use `input` types, hence TypeGraphQL allows us to create inputs in the same way as [object types](./types-and-fields.md) but by using the `@InputType()` decorator: + +```ts +@InputType() +class AddRecipeInput {} +``` + +To ensure we don't accidentally change the property type we leverage the TypeScript type checking system by implementing the `Partial` type: + +```ts +@InputType() +class AddRecipeInput implements Partial {} +``` + +We then declare any input fields we need, using the `@Field()` decorator: + +```ts +@InputType({ description: "New recipe data" }) +class AddRecipeInput implements Partial { + @Field() + title: string; + + @Field({ nullable: true }) + description?: string; +} +``` + +After that we can use the `AddRecipeInput` type in our mutation. We can do this inline (using the `@Arg()` decorator) or as a field of the args class like in the query example above. + +We may also need access to the context. To achieve this we use the `@Ctx()` decorator with the optional user-defined `Context` interface: + +```ts +@Resolver() +class RecipeResolver { + // ... + @Mutation() + addRecipe(@Arg("data") newRecipeData: AddRecipeInput, @Ctx() ctx: Context): Recipe { + // Example implementation + const recipe = RecipesUtils.create(newRecipeData, ctx.user); + this.recipesCollection.push(recipe); + return recipe; + } +} +``` + +Because our method is synchronous and explicitly returns `Recipe`, we can omit the `@Mutation()` type annotation. + +This declaration will result in the following part of the schema in SDL: + +```graphql +input AddRecipeInput { + title: String! + description: String +} +``` + +```graphql +type Mutation { + addRecipe(data: AddRecipeInput!): Recipe! +} +``` + +By using parameter decorators, we can get rid of unnecessary parameters (like `root`) that bloat our method definition and have to be ignored by prefixing the parameter name with `_`. Also, we can achieve a clean separation between GraphQL and our business code by using decorators, so our resolvers and their methods behave just like services which can be easily unit-tested. + +## Field resolvers + +Queries and mutations are not the only type of resolvers. We often create object type field resolvers (e.g. when a `user` type has a `posts` field) which we have to resolve by fetching relational data from the database. + +Field resolvers in TypeGraphQL are very similar to queries and mutations - we create them as a method on the resolver class but with a few modifications. First we declare which object type fields we are resolving by providing the type to the `@Resolver` decorator: + +```ts +@Resolver(of => Recipe) +class RecipeResolver { + // Queries and mutations +} +``` + +Then we create a class method that will become the field resolver. +In our example we have the `averageRating` field in the `Recipe` object type that should calculate the average from the `ratings` array. + +```ts +@Resolver(of => Recipe) +class RecipeResolver { + // Queries and mutations + + averageRating(recipe: Recipe) { + // ... + } +} +``` + +We then mark the method as a field resolver with the `@FieldResolver()` decorator. Since we've already defined the field type in the `Recipe` class definition, there's no need to redefine it. We also decorate the method parameters with the `@Root` decorator in order to inject the recipe object. + +```ts +@Resolver(of => Recipe) +class RecipeResolver { + // Queries and mutations + + @FieldResolver() + averageRating(@Root() recipe: Recipe) { + // ... + } +} +``` + +For enhanced type safety we can implement the `ResolverInterface` interface. +It's a small helper that checks if the return type of the field resolver methods, like `averageRating(...)`, matches the `averageRating` property of the `Recipe` class and whether the first parameter of the method is the actual object type (`Recipe` class). + +```ts +@Resolver(of => Recipe) +class RecipeResolver implements ResolverInterface { + // Queries and mutations + + @FieldResolver() + averageRating(@Root() recipe: Recipe) { + // ... + } +} +``` + +Here is the full implementation of the sample `averageRating` field resolver: + +```ts +@Resolver(of => Recipe) +class RecipeResolver implements ResolverInterface { + // Queries and mutations + + @FieldResolver() + averageRating(@Root() recipe: Recipe) { + const ratingsSum = recipe.ratings.reduce((a, b) => a + b, 0); + return recipe.ratings.length ? ratingsSum / recipe.ratings.length : null; + } +} +``` + +For simple resolvers like `averageRating` or deprecated fields that behave like aliases, you can create field resolvers inline in the object type class definition: + +```ts +@ObjectType() +class Recipe { + @Field() + title: string; + + @Field({ deprecationReason: "Use `title` instead" }) + get name(): string { + return this.title; + } + + @Field(type => [Rate]) + ratings: Rate[]; + + @Field(type => Float, { nullable: true }) + averageRating(@Arg("since") sinceDate: Date): number | null { + const ratings = this.ratings.filter(rate => rate.date > sinceDate); + if (!ratings.length) return null; + + const ratingsSum = ratings.reduce((a, b) => a + b, 0); + return ratingsSum / ratings.length; + } +} +``` + +However, if the code is more complicated and has side effects (i.e. api calls, fetching data from a databases), a resolver class method should be used instead. This way we can leverage the dependency injection mechanism, which is really helpful in testing. For example: + +```ts +import { Repository } from "typeorm"; + +@Resolver(of => Recipe) +class RecipeResolver implements ResolverInterface { + constructor( + // Dependency injection + private readonly userRepository: Repository, + ) {} + + @FieldResolver() + async author(@Root() recipe: Recipe) { + const author = await this.userRepository.findById(recipe.userId); + if (!author) throw new SomethingWentWrongError(); + return author; + } +} +``` + +Note that if a field name of a field resolver doesn't exist in the resolver object type, it will create a field in the schema with this name. This feature is useful when the field is purely calculable (eg. `averageRating` from `ratings` array) and to avoid polluting the class signature. + +## Resolver Inheritance + +Resolver class `inheritance` is an advanced topic covered in the [resolver inheritance docs](./inheritance.md#resolvers-inheritance). + +## Examples + +These code samples are just made up for tutorial purposes. +You can find more advanced, real examples in the [examples folder on the repository](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples). diff --git a/website/versioned_docs/version-2.0.0-beta.4/subscriptions.md b/website/versioned_docs/version-2.0.0-beta.4/subscriptions.md new file mode 100644 index 000000000..3edaef5e5 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.4/subscriptions.md @@ -0,0 +1,214 @@ +--- +title: Subscriptions +id: version-2.0.0-beta.4-subscriptions +original_id: subscriptions +--- + +GraphQL can be used to perform reads with queries and writes with mutations. +However, oftentimes clients want to get updates pushed to them from the server when data they care about changes. +To support that, GraphQL has a third operation: subscription. TypeGraphQL of course has great support for subscription, using the [`@graphql-yoga/subscriptions`](https://the-guild.dev/graphql/yoga-server/docs/features/subscriptions) package created by [`The Guild`](https://the-guild.dev/). + +## Creating Subscriptions + +Subscription resolvers are similar to [queries and mutation resolvers](./resolvers.md) but slightly more complicated. + +First we create a normal class method as always, but this time annotated with the `@Subscription()` decorator. + +```ts +class SampleResolver { + // ... + @Subscription() + newNotification(): Notification { + // ... + } +} +``` + +Then we have to provide the topics we wish to subscribe to. This can be a single topic string, an array of topics or a function to dynamically create a topic based on subscription arguments passed to the query. We can also use TypeScript enums for enhanced type safety. + +```ts +class SampleResolver { + // ... + @Subscription({ + topics: "NOTIFICATIONS", // Single topic + topics: ["NOTIFICATIONS", "ERRORS"] // Or topics array + topics: ({ args, context }) => args.topic // Or dynamic topic function + }) + newNotification(): Notification { + // ... + } +} +``` + +We can also provide the `filter` option to decide which topic events should trigger our subscription. +This function should return a `boolean` or `Promise` type. + +```ts +class SampleResolver { + // ... + @Subscription({ + topics: "NOTIFICATIONS", + filter: ({ payload, args }) => args.priorities.includes(payload.priority), + }) + newNotification(): Notification { + // ... + } +} +``` + +We can also provide a custom subscription logic which might be useful, e.g. if we want to use the Prisma subscription functionality or something similar. + +All we need to do is to use the `subscribe` option which should be a function that returns an `AsyncIterable` or a `Promise`. Example using Prisma 1 subscription feature: + +```ts +class SampleResolver { + // ... + @Subscription({ + subscribe: (root, args, context, info) => { + return context.prisma.$subscribe.users({ mutation_in: [args.mutationType] }); + }, + }) + newNotification(): Notification { + // ... + } +} +``` + +> Be aware that we can't mix the `subscribe` option with the `topics` and `filter` options. If the filtering is still needed, we can use the [`filter` and `map` helpers](https://the-guild.dev/graphql/yoga-server/docs/features/subscriptions#filter-and-map-values) from the `@graphql-yoga/subscriptions` package. + +Now we can implement the subscription resolver. It will receive the payload from a triggered topic of the pubsub system using the `@Root()` decorator. There, we can transform it to the returned shape. + +```ts +class SampleResolver { + // ... + @Subscription({ + topics: "NOTIFICATIONS", + filter: ({ payload, args }) => args.priorities.includes(payload.priority), + }) + newNotification( + @Root() notificationPayload: NotificationPayload, + @Args() args: NewNotificationsArgs, + ): Notification { + return { + ...notificationPayload, + date: new Date(), + }; + } +} +``` + +## Triggering subscription topics + +Ok, we've created subscriptions, but what is the `pubsub` system and how do we trigger topics? + +They might be triggered from external sources like a database but also in mutations, +e.g. when we modify some resource that clients want to receive notifications about when it changes. + +So, let us assume we have this mutation for adding a new comment: + +```ts +class SampleResolver { + // ... + @Mutation(returns => Boolean) + async addNewComment(@Arg("comment") input: CommentInput) { + const comment = this.commentsService.createNew(input); + await this.commentsRepository.save(comment); + return true; + } +} +``` + +First, we need to create the `PubSub` instance. In most cases, we call `createPubSub()` function from `@graphql-yoga/subscriptions` package. Optionally, we can define the used topics and payload type using the type argument, e.g.: + +```ts +import { createPubSub } from "@graphql-yoga/subscriptions"; + +export const pubSub = createPubSub<{ + NOTIFICATIONS: [NotificationPayload]; + DYNAMIC_ID_TOPIC: [number, NotificationPayload]; +}>(); +``` + +Then, we need to register the `PubSub` instance in the `buildSchema()` function options: + +```ts +import { buildSchema } from "type-graphql"; +import { pubSub } from "./pubsub"; + +const schema = await buildSchema({ + resolver, + pubSub, +}); +``` + +Finally, we can use the created `PubSub` instance to trigger the topics and send the payload to all topic subscribers: + +```ts +import { pubSub } from "./pubsub"; + +class SampleResolver { + // ... + @Mutation(returns => Boolean) + async addNewComment(@Arg("comment") input: CommentInput, @PubSub() pubSub: PubSubEngine) { + const comment = this.commentsService.createNew(input); + await this.commentsRepository.save(comment); + // Trigger subscriptions topics + const payload: NotificationPayload = { message: input.content }; + pubSub.publish("NOTIFICATIONS", payload); + return true; + } +} +``` + +And that's it! Now all subscriptions attached to the `NOTIFICATIONS` topic will be triggered when performing the `addNewComment` mutation. + +## Topic with dynamic ID + +The idea of this feature is taken from the `@graphql-yoga/subscriptions` that is used under the hood. +Basically, sometimes you only want to emit and listen for events for a specific entity (e.g. user or product). Dynamic topic ID lets you declare topics scoped to a special identifier, e.g.: + +```ts +@Resolver() +class NotificationResolver { + @Subscription({ + topics: "NOTIFICATIONS", + topicId: ({ context }) => context.userId, + }) + newNotification(@Root() { message }: NotificationPayload): Notification { + return { message, date: new Date() }; + } +} +``` + +Then in your mutation or services, you need to pass the topic id as the second parameter: + +```ts +pubSub.publish("NOTIFICATIONS", userId, { id, message }); +``` + +> Be aware that this feature must be supported by the pubsub system of your choice. +> If you decide to use something different than `createPubSub()` from `@graphql-yoga/subscriptions`, the second argument might be treated as a payload, not dynamic topic id. + +## Using a custom PubSub system + +While TypeGraphQL uses the `@graphql-yoga/subscriptions` package under the hood to handle subscription, there's no requirement to use that implementation of `PubSub`. + +In fact, you can use any pubsub system you want, not only the `graphql-yoga` one. +The only requirement is to comply with the exported `PubSub` interface - having proper `.subscribe()` and `.publish()` methods. + +This is especially helpful for production usage, where we can't rely on the in-memory event emitter, so that we [use distributed pubsub](https://the-guild.dev/graphql/yoga-server/docs/features/subscriptions#distributed-pubsub-for-production). + +## Creating a Subscription Server + +The [bootstrap guide](./bootstrap.md) and all the earlier examples used [`apollo-server`](https://github.com/apollographql/apollo-server) to create an HTTP endpoint for our GraphQL API. + +However, beginning in Apollo Server 3, subscriptions are not supported by the "batteries-included" apollo-server package. To enable subscriptions, you need to follow the guide on their docs page: + + +## Examples + +See how subscriptions work in a [simple example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/simple-subscriptions). You can see there, how simple is setting up GraphQL subscriptions using `graphql-yoga` package. + + + diff --git a/website/versioned_docs/version-2.0.0-beta.4/unions.md b/website/versioned_docs/version-2.0.0-beta.4/unions.md new file mode 100644 index 000000000..245faf4cb --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.4/unions.md @@ -0,0 +1,109 @@ +--- +title: Unions +id: version-2.0.0-beta.4-unions +original_id: unions +--- + +Sometimes our API has to be flexible and return a type that is not specific but one from a range of possible types. An example might be a movie site's search functionality: using the provided phrase we search the database for movies but also actors. So the query has to return a list of `Movie` or `Actor` types. + +Read more about the GraphQL Union Type in the [official GraphQL docs](http://graphql.org/learn/schema/#union-types). + +## Usage + +Let's start by creating the object types from the example above: + +```ts +@ObjectType() +class Movie { + @Field() + name: string; + + @Field() + rating: number; +} +``` + +```ts +@ObjectType() +class Actor { + @Field() + name: string; + + @Field(type => Int) + age: number; +} +``` + +Now let's create an union type from the object types above - the rarely seen `[ ] as const` syntax is to inform TypeScript compiler that it's a tuple, which allows for better TS union type inference: + +```ts +import { createUnionType } from "type-graphql"; + +const SearchResultUnion = createUnionType({ + name: "SearchResult", // Name of the GraphQL union + types: () => [Movie, Actor] as const, // function that returns tuple of object types classes +}); +``` + +Then we can use the union type in the query by providing the `SearchResultUnion` value in the `@Query` decorator return type annotation. +Notice, that we have to explicitly use the decorator return type annotation due to TypeScript's reflection limitations. +For TypeScript compile-time type safety we can also use `typeof SearchResultUnion` which is equal to type `Movie | Actor`. + +```ts +@Resolver() +class SearchResolver { + @Query(returns => [SearchResultUnion]) + async search(@Arg("phrase") phrase: string): Promise> { + const movies = await Movies.findAll(phrase); + const actors = await Actors.findAll(phrase); + + return [...movies, ...actors]; + } +} +``` + +## Resolving Type + +Be aware that when the query/mutation return type (or field type) is a union, we have to return a specific instance of the object type class. Otherwise, `graphql-js` will not be able to detect the underlying GraphQL type correctly when we use plain JS objects. + +However, we can also provide our own `resolveType` function implementation to the `createUnionType` options. This way we can return plain objects in resolvers and then determine the returned object type by checking the shape of the data object, e.g.: + +```ts +const SearchResultUnion = createUnionType({ + name: "SearchResult", + types: () => [Movie, Actor] as const, + // Implementation of detecting returned object type + resolveType: value => { + if ("rating" in value) { + return Movie; // Return object type class (the one with `@ObjectType()`) + } + if ("age" in value) { + return "Actor"; // Or the schema name of the type as a string + } + return undefined; + }, +}); +``` + +**Et VoilΓ !** We can now build the schema and make the example query πŸ˜‰ + +```graphql +query { + search(phrase: "Holmes") { + ... on Actor { + # Maybe Katie Holmes? + name + age + } + ... on Movie { + # For sure Sherlock Holmes! + name + rating + } + } +} +``` + +## Examples + +More advanced usage examples of unions (and enums) are located in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/enums-and-unions). diff --git a/website/versioned_docs/version-2.0.0-beta.4/validation.md b/website/versioned_docs/version-2.0.0-beta.4/validation.md new file mode 100644 index 000000000..ef2151c12 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.4/validation.md @@ -0,0 +1,258 @@ +--- +title: Argument and Input validation +sidebar_label: Validation +id: version-2.0.0-beta.4-validation +original_id: validation +--- + +## Scalars + +The standard way to ensure that inputs and arguments are correct, such as an `email` field that really contains a proper e-mail address, is to use [custom scalars](./scalars.md) e.g. `GraphQLEmail` from [`graphql-custom-types`](https://github.com/stylesuxx/graphql-custom-types). However, creating scalars for all single cases of data types (credit card number, base64, IP, URL) might be cumbersome. + +That's why TypeGraphQL has built-in support for argument and input validation. +By default, we can use the [`class-validator`](https://github.com/typestack/class-validator) library and easily declare the requirements for incoming data (e.g. a number is in the range 0-255 or a password that is longer than 8 characters) thanks to the awesomeness of decorators. + +We can also use other libraries or our own custom solution, as described in [custom validators](#custom-validator) section. + +## `class-validator` + +### How to use + +First, we need to install the `class-validator` package: + +```sh +npm install class-validator +``` + +Then we decorate the input/arguments class with the appropriate decorators from `class-validator`. +So we take this: + +```ts +@InputType() +export class RecipeInput { + @Field() + title: string; + + @Field({ nullable: true }) + description?: string; +} +``` + +...and turn it into this: + +```ts +import { MaxLength, Length } from "class-validator"; + +@InputType() +export class RecipeInput { + @Field() + @MaxLength(30) + title: string; + + @Field({ nullable: true }) + @Length(30, 255) + description?: string; +} +``` + +Then we need to enable the auto-validate feature (as it's disabled by default) by simply setting `validate: true` in `buildSchema` options, e.g.: + +```ts +const schema = await buildSchema({ + resolvers: [RecipeResolver], + validate: true, // Enable 'class-validator' integration +}); +``` + +And that's it! πŸ˜‰ + +TypeGraphQL will automatically validate our inputs and arguments based on the definitions: + +```ts +@Resolver(of => Recipe) +export class RecipeResolver { + @Mutation(returns => Recipe) + async addRecipe(@Arg("input") recipeInput: RecipeInput): Promise { + // 100% sure that the input is correct + console.assert(recipeInput.title.length <= 30); + console.assert(recipeInput.description.length >= 30); + console.assert(recipeInput.description.length <= 255); + } +} +``` + +Of course, [there are many more decorators](https://github.com/typestack/class-validator#validation-decorators) we have access to, not just the simple `@Length` decorator used in the example above, so take a look at the `class-validator` documentation. + +This feature is enabled by default. However, we can disable it if we must: + +```ts +const schema = await buildSchema({ + resolvers: [RecipeResolver], + validate: false, // Disable automatic validation or pass the default config object +}); +``` + +And we can still enable it per resolver's argument if we need to: + +```ts +class RecipeResolver { + @Mutation(returns => Recipe) + async addRecipe(@Arg("input", { validate: true }) recipeInput: RecipeInput) { + // ... + } +} +``` + +The `ValidatorOptions` object used for setting features like [validation groups](https://github.com/typestack/class-validator#validation-groups) can also be passed: + +```ts +class RecipeResolver { + @Mutation(returns => Recipe) + async addRecipe( + @Arg("input", { validate: { groups: ["admin"] } }) + recipeInput: RecipeInput, + ) { + // ... + } +} +``` + +Note that by default, the `skipMissingProperties` setting of the `class-validator` is set to `true` because GraphQL will independently check whether the params/fields exist or not. +Same goes to `forbidUnknownValues` setting which is set to `false` because the GraphQL runtime checks for additional data, not described in schema. + +GraphQL will also check whether the fields have correct types (String, Int, Float, Boolean, etc.) so we don't have to use the `@IsOptional`, `@Allow`, `@IsString` or the `@IsInt` decorators at all! + +However, when using nested input or arrays, we always have to use [`@ValidateNested()` decorator](https://github.com/typestack/class-validator#validating-nested-objects) or [`{ each: true }` option](https://github.com/typestack/class-validator#validating-arrays) to make nested validation work properly. + +### Response to the Client + +When a client sends incorrect data to the server: + +```graphql +mutation ValidationMutation { + addRecipe( + input: { + # Too long! + title: "Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet" + } + ) { + title + creationDate + } +} +``` + +the [`ArgumentValidationError`](https://github.com/MichalLytek/type-graphql/blob/master/src/errors/ArgumentValidationError.ts) will be thrown. + +By default, the `apollo-server` package from the [bootstrap guide](./bootstrap.md) will format the error to match the `GraphQLFormattedError` interface. So when the `ArgumentValidationError` occurs, the client will receive this JSON with a nice `validationErrors` property inside of `extensions.exception`: + +```json +{ + "errors": [ + { + "message": "Argument Validation Error", + "locations": [ + { + "line": 2, + "column": 3 + } + ], + "path": ["addRecipe"], + "extensions": { + "code": "INTERNAL_SERVER_ERROR", + "exception": { + "validationErrors": [ + { + "target": { + "title": "Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet" + }, + "value": "Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet", + "property": "title", + "children": [], + "constraints": { + "maxLength": "title must be shorter than or equal to 30 characters" + } + } + ], + "stacktrace": [ + "Error: Argument Validation Error", + " at Object. (/type-graphql/src/resolvers/validate-arg.ts:29:11)", + " at Generator.throw ()", + " at rejected (/type-graphql/node_modules/tslib/tslib.js:105:69)", + " at processTicksAndRejections (internal/process/next_tick.js:81:5)" + ] + } + } + } + ], + "data": null +} +``` + +Of course we can also create our own custom implementation of the `formatError` function provided in the `ApolloServer` config options which will transform the `GraphQLError` with a `ValidationError` array in the desired output format (e.g. `extensions.code = "ARGUMENT_VALIDATION_ERROR"`). + +### Automatic Validation Example + +To see how this works, check out the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/automatic-validation). + +### Caveats + +Even if we don't use the validation feature (and we have provided `{ validate: false }` option to `buildSchema`), we still need to have `class-validator` installed as a dev dependency in order to compile our app without errors using `tsc`. + +An alternative solution that allows to completely get rid off big `class-validator` from our project's `node_modules` folder is to suppress the `error TS2307: Cannot find module 'class-validator'` TS error by providing `"skipLibCheck": true` setting in `tsconfig.json`. + +## Custom validator + +We can also use other libraries than `class-validator` together with TypeGraphQL. + +To integrate it, all we need to do is to provide a custom function. +It receives three parameters: + +- `argValue` which is the injected value of `@Arg()` or `@Args()` +- `argType` which is a runtime type information (e.g. `String` or `RecipeInput`) +- `resolverData` which holds the resolver execution context, described as generic type `ResolverData` + +This function can be an async function and should return nothing (`void`) when validation passes, or throw an error when validation fails. +So be aware of this while trying to wrap another library in `validateFn` function for TypeGraphQL. + +Then we provide this function as a `validateFn` option in `buildSchema`. +Example using [decorators library for Joi validators (`joiful`)](https://github.com/joiful-ts/joiful): + +```ts +const schema = await buildSchema({ + // ... + validateFn: argValue => { + // Call joiful validate + const { error } = joiful.validate(argValue); + if (error) { + // Throw error on failed validation + throw error; + } + }, +}); +``` + +The `validateFn` option is also supported as a `@Arg()` or `@Args()` decorator option, e.g.: + +```ts +@Resolver() +class SampleResolver { + @Query() + sampleQuery( + @Arg("sampleArg", { + validateFn: (argValue, argType) => { + // Do something here with arg value and type... + }, + }) + sampleArg: string, + ): string { + // ... + } +} +``` + +> Be aware that when using custom validator, the error won't be wrapped with `ArgumentValidationError` like for the built-in `class-validator` validation. + +### Custom Validation Example + +To see how this works, check out the [simple custom validation integration example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.4/examples/custom-validation). diff --git a/website/versioned_docs/version-2.0.0-beta.6/authorization.md b/website/versioned_docs/version-2.0.0-beta.6/authorization.md new file mode 100644 index 000000000..e4f777b8b --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.6/authorization.md @@ -0,0 +1,195 @@ +--- +title: Authorization +id: version-2.0.0-beta.6-authorization +original_id: authorization +--- + +Authorization is a core feature used in almost all APIs. Sometimes we want to restrict data access or actions for a specific group of users. + +In express.js (and other Node.js frameworks) we use middleware for this, like `passport.js` or the custom ones. However, in GraphQL's resolver architecture we don't have middleware so we have to imperatively call the auth checking function and manually pass context data to each resolver, which might be a bit tedious. + +That's why authorization is a first-class feature in `TypeGraphQL`! + +## How to use + +First, we need to use the `@Authorized` decorator as a guard on a field, query or mutation. +Example object type field guards: + +```ts +@ObjectType() +class MyObject { + @Field() + publicField: string; + + @Authorized() + @Field() + authorizedField: string; + + @Authorized("ADMIN") + @Field() + adminField: string; + + @Authorized(["ADMIN", "MODERATOR"]) + @Field({ nullable: true }) + hiddenField?: string; +} +``` + +We can leave the `@Authorized` decorator brackets empty or we can specify the role/roles that the user needs to possess in order to get access to the field, query or mutation. +By default the roles are of type `string` but they can easily be changed as the decorator is generic - `@Authorized(1, 7, 22)`. + +Thus, authorized users (regardless of their roles) can only read the `publicField` or the `authorizedField` from the `MyObject` object. They will receive `null` when accessing the `hiddenField` field and will receive an error (that will propagate through the whole query tree looking for a nullable field) for the `adminField` when they don't satisfy the role constraints. + +Sample query and mutation guards: + +```ts +@Resolver() +class MyResolver { + @Query() + publicQuery(): MyObject { + return { + publicField: "Some public data", + authorizedField: "Data for logged users only", + adminField: "Top secret info for admin", + }; + } + + @Authorized() + @Query() + authedQuery(): string { + return "Authorized users only!"; + } + + @Authorized("ADMIN", "MODERATOR") + @Mutation() + adminMutation(): string { + return "You are an admin/moderator, you can safely drop the database ;)"; + } +} +``` + +Authorized users (regardless of their roles) will be able to read data from the `publicQuery` and the `authedQuery` queries, but will receive an error when trying to perform the `adminMutation` when their roles don't include `ADMIN` or `MODERATOR`. + +Next, we need to create our auth checker function. Its implementation may depend on our business logic: + +```ts +export const customAuthChecker: AuthChecker = ( + { root, args, context, info }, + roles, +) => { + // Read user from context + // and check the user's permission against the `roles` argument + // that comes from the '@Authorized' decorator, eg. ["ADMIN", "MODERATOR"] + + return true; // or 'false' if access is denied +}; +``` + +The second argument of the `AuthChecker` generic type is `RoleType` - used together with the `@Authorized` decorator generic type. + +Auth checker can be also defined as a class - this way we can leverage the dependency injection mechanism: + +```ts +export class CustomAuthChecker implements AuthCheckerInterface { + constructor( + // Dependency injection + private readonly userRepository: Repository, + ) {} + + check({ root, args, context, info }: ResolverData, roles: string[]) { + const userId = getUserIdFromToken(context.token); + // Use injected service + const user = this.userRepository.getById(userId); + + // Custom logic, e.g.: + return user % 2 === 0; + } +} +``` + +The last step is to register the function or class while building the schema: + +```ts +import { customAuthChecker } from "../auth/custom-auth-checker.ts"; + +const schema = await buildSchema({ + resolvers: [MyResolver], + // Register the auth checking function + // or defining it inline + authChecker: customAuthChecker, +}); +``` + +And it's done! πŸ˜‰ + +If we need silent auth guards and don't want to return authorization errors to users, we can set the `authMode` property of the `buildSchema` config object to `"null"`: + +```ts +const schema = await buildSchema({ + resolvers: ["./**/*.resolver.ts"], + authChecker: customAuthChecker, + authMode: "null", +}); +``` + +It will then return `null` instead of throwing an authorization error. + +## Recipes + +We can also use `TypeGraphQL` with JWT authentication. +Here's an example using `@apollo/server`: + +```ts +import { ApolloServer } from "@apollo/server"; +import { expressMiddleware } from "@apollo/server/express4"; +import express from "express"; +import jwt from "express-jwt"; +import bodyParser from "body-parser"; +import { schema } from "./graphql/schema"; +import { User } from "./User.type"; + +// GraphQL path +const GRAPHQL_PATH = "/graphql"; + +// GraphQL context +type Context = { + user?: User; +}; + +// Express +const app = express(); + +// Apollo server +const server = new ApolloServer({ schema }); +await server.start(); + +// Mount a JWT or other authentication middleware that is run before the GraphQL execution +app.use( + GRAPHQL_PATH, + jwt({ + secret: "TypeGraphQL", + credentialsRequired: false, + }), +); + +// Apply GraphQL server middleware +app.use( + GRAPHQL_PATH, + bodyParser.json(), + expressMiddleware(server, { + // Build context + // 'req.user' comes from 'express-jwt' + context: async ({ req }) => ({ user: req.user }), + }), +); + +// Start server +await new Promise(resolve => app.listen({ port: 4000 }, resolve)); +console.log(`GraphQL server ready at http://localhost:4000/${GRAPHQL_PATH}`); +``` + +Then we can use standard, token based authorization in the HTTP header like in classic REST APIs and take advantage of the `TypeGraphQL` authorization mechanism. + +## Example + +See how this works in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/authorization). diff --git a/website/versioned_docs/version-2.0.0-beta.6/complexity.md b/website/versioned_docs/version-2.0.0-beta.6/complexity.md new file mode 100644 index 000000000..c442f44d7 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.6/complexity.md @@ -0,0 +1,103 @@ +--- +title: Query complexity +id: version-2.0.0-beta.6-complexity +original_id: complexity +--- + +A single GraphQL query can potentially generate a huge workload for a server, like thousands of database operations which can be used to cause DDoS attacks. In order to limit and keep track of what each GraphQL operation can do, `TypeGraphQL` provides the option of integrating with Query Complexity tools like [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity). + +This cost analysis-based solution is very promising, since we can define a β€œcost” per field and then analyze the AST to estimate the total cost of the GraphQL query. Of course all the analysis is handled by `graphql-query-complexity`. + +All we must do is define our complexity cost for the fields, mutations or subscriptions in `TypeGraphQL` and implement `graphql-query-complexity` in whatever GraphQL server that is being used. + +## How to use + +First, we need to pass `complexity` as an option to the decorator on a field, query or mutation. + +Example of complexity + +```ts +@ObjectType() +class MyObject { + @Field({ complexity: 2 }) + publicField: string; + + @Field({ complexity: ({ args, childComplexity }) => childComplexity + 1 }) + complexField: string; +} +``` + +The `complexity` option may be omitted if the complexity value is 1. +Complexity can be passed as an option to any `@Field`, `@FieldResolver`, `@Mutation` or `@Subscription` decorator. If both `@FieldResolver` and `@Field` decorators of the same property have complexity defined, then the complexity passed to the field resolver decorator takes precedence. + +In the next step, we will integrate `graphql-query-complexity` with the server that expose our GraphQL schema over HTTP. +You can use it with `express-graphql` like [in the lib examples](https://github.com/slicknode/graphql-query-complexity/blob/b6a000c0984f7391f3b4e886e3df6a7ed1093b07/README.md#usage-with-express-graphql), however we will use Apollo Server like in our other examples: + +```ts +async function bootstrap() { + // ... Build GraphQL schema + + // Create GraphQL server + const server = new ApolloServer({ + schema, + // Create a plugin to allow query complexity calculation for every request + plugins: [ + { + requestDidStart: async () => ({ + async didResolveOperation({ request, document }) { + /** + * Provides GraphQL query analysis to be able to react on complex queries to the GraphQL server + * It can be used to protect the GraphQL server against resource exhaustion and DoS attacks + * More documentation can be found at https://github.com/ivome/graphql-query-complexity + */ + const complexity = getComplexity({ + // GraphQL schema + schema, + // To calculate query complexity properly, + // check only the requested operation + // not the whole document that may contains multiple operations + operationName: request.operationName, + // GraphQL query document + query: document, + // GraphQL query variables + variables: request.variables, + // Add any number of estimators. The estimators are invoked in order, the first + // numeric value that is being returned by an estimator is used as the field complexity + // If no estimator returns a value, an exception is raised + estimators: [ + // Using fieldExtensionsEstimator is mandatory to make it work with type-graphql + fieldExtensionsEstimator(), + // Add more estimators here... + // This will assign each field a complexity of 1 + // if no other estimator returned a value + simpleEstimator({ defaultComplexity: 1 }), + ], + }); + + // React to the calculated complexity, + // like compare it with max and throw error when the threshold is reached + if (complexity > MAX_COMPLEXITY) { + throw new Error( + `Sorry, too complicated query! ${complexity} exceeded the maximum allowed complexity of ${MAX_COMPLEXITY}`, + ); + } + console.log("Used query complexity points:", complexity); + }, + }), + }, + ], + }); + + // Start server + const { url } = await startStandaloneServer(server, { listen: { port: 4000 } }); + console.log(`GraphQL server ready at ${url}`); +} +``` + +And it's done! πŸ˜‰ + +For more info about how query complexity is computed, please visit [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity). + +## Example + +See how this works in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/query-complexity). diff --git a/website/versioned_docs/version-2.0.0-beta.6/custom-decorators.md b/website/versioned_docs/version-2.0.0-beta.6/custom-decorators.md new file mode 100644 index 000000000..752f3fa3e --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.6/custom-decorators.md @@ -0,0 +1,109 @@ +--- +title: Custom decorators +id: version-2.0.0-beta.6-custom-decorators +original_id: custom-decorators +--- + +Custom decorators are a great way to reduce the boilerplate and reuse some common logic between different resolvers. TypeGraphQL supports two kinds of custom decorators - method and parameter. + +## Method decorators + +Using [middlewares](./middlewares.md) allows to reuse some code between resolvers. To further reduce the boilerplate and have a nicer API, we can create our own custom method decorators. + +They work in the same way as the [reusable middleware function](./middlewares.md#reusable-middleware), however, in this case we need to call `createMethodDecorator` helper function with our middleware logic and return its value: + +```ts +export function ValidateArgs(schema: JoiSchema) { + return createMethodDecorator(async ({ args }, next) => { + // Middleware code that uses custom decorator arguments + + // e.g. Validation logic based on schema using 'joi' + await joiValidate(schema, args); + return next(); + }); +} +``` + +The usage is then very simple, as we have a custom, descriptive decorator - we just place it above the resolver/field and pass the required arguments to it: + +```ts +@Resolver() +export class RecipeResolver { + @ValidateArgs(MyArgsSchema) // Custom decorator + @UseMiddleware(ResolveTime) // Explicit middleware + @Query() + randomValue(@Args() { scale }: MyArgs): number { + return Math.random() * scale; + } +} +``` + +## Parameter decorators + +Parameter decorators are just like the custom method decorators or middlewares but with an ability to return some value that will be injected to the method as a parameter. Thanks to this, it reduces the pollution in `context` which was used as a workaround for the communication between reusable middlewares and resolvers. + +They might be just a simple data extractor function, that makes our resolver more unit test friendly: + +```ts +function CurrentUser() { + return createParamDecorator(({ context }) => context.currentUser); +} +``` + +Or might be a more advanced one that performs some calculations and encapsulates some logic. Compared to middlewares, they allows for a more granular control on executing the code, like calculating fields map based on GraphQL info only when it's really needed (requested by using the `@Fields()` decorator): + +```ts +function Fields(level = 1): ParameterDecorator { + return createParamDecorator(async ({ info }) => { + const fieldsMap: FieldsMap = {}; + // Calculate an object with info about requested fields + // based on GraphQL 'info' parameter of the resolver and the level parameter + // or even call some async service, as it can be a regular async function and we can just 'await' + return fieldsMap; + }); +} +``` + +> Be aware, that `async` function as a custom param decorators logic can make the GraphQL resolver execution slower, so try to avoid them, if possible. + +Then we can use our custom param decorators in the resolvers just like the built-in decorators: + +```ts +@Resolver() +export class RecipeResolver { + constructor(private readonly recipesRepository: Repository) {} + + @Authorized() + @Mutation(returns => Recipe) + async addRecipe( + @Args() recipeData: AddRecipeInput, + // Custom decorator just like the built-in one + @CurrentUser() currentUser: User, + ) { + const recipe: Recipe = { + ...recipeData, + // and use the data returned from custom decorator in the resolver code + author: currentUser, + }; + await this.recipesRepository.save(recipe); + + return recipe; + } + + @Query(returns => Recipe, { nullable: true }) + async recipe( + @Arg("id") id: string, + // Custom decorator that parses the fields from GraphQL query info + @Fields() fields: FieldsMap, + ) { + return await this.recipesRepository.find(id, { + // use the fields map as a select projection to optimize db queries + select: fields, + }); + } +} +``` + +## Example + +See how different kinds of custom decorators work in the [custom decorators and middlewares example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/middlewares-custom-decorators). diff --git a/website/versioned_docs/version-2.0.0-beta.6/dependency-injection.md b/website/versioned_docs/version-2.0.0-beta.6/dependency-injection.md new file mode 100644 index 000000000..c78b5a975 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.6/dependency-injection.md @@ -0,0 +1,180 @@ +--- +title: Dependency injection +id: version-2.0.0-beta.6-dependency-injection +original_id: dependency-injection +--- + +Dependency injection is a really useful pattern that helps in decoupling parts of the app. + +TypeGraphQL supports this technique by allowing users to provide their IoC container that will be used by the framework. + +## Basic usage + +The usage of this feature is very simple - all you need to do is register a 3rd party container. + +Example using TypeDI: + +```ts +import { buildSchema } from "type-graphql"; +// IOC container +import { Container } from "typedi"; +import { SampleResolver } from "./resolvers"; + +// Build TypeGraphQL executable schema +const schema = await buildSchema({ + // Array of resolvers + resolvers: [SampleResolver], + // Registry 3rd party IOC container + container: Container, +}); +``` + +Resolvers will then be able to declare their dependencies and TypeGraphQL will use the container to solve them: + +```ts +import { Service } from "typedi"; + +@Service() +@Resolver(of => Recipe) +export class RecipeResolver { + constructor( + // Dependency injection + private readonly recipeService: RecipeService, + ) {} + + @Query(returns => Recipe, { nullable: true }) + async recipe(@Arg("recipeId") recipeId: string) { + // Usage of the injected service + return this.recipeService.getOne(recipeId); + } +} +``` + +A sample recipe service implementation may look like this: + +```ts +import { Service, Inject } from "typedi"; + +@Service() +export class RecipeService { + @Inject("SAMPLE_RECIPES") + private readonly items: Recipe[], + + async getAll() { + return this.items; + } + + async getOne(id: string) { + return this.items.find(item => item.id === id); + } +} +``` + +> Be aware than when you use [InversifyJS](https://github.com/inversify/InversifyJS), you have to bind the resolver class with the [self-binding of concrete types](https://github.com/inversify/InversifyJS/blob/master/wiki/classes_as_id.md#self-binding-of-concrete-types), e.g.: +> +> ```ts +> container.bind(SampleResolver).to(SampleResolver).inSingletonScope(); +> ``` + +## Scoped containers + +Dependency injection is a really powerful pattern, but some advanced users may encounter the need for creating fresh instances of some services or resolvers for every request. Since `v0.13.0`, **TypeGraphQL** supports this feature, that is extremely useful for tracking logs by individual requests or managing stateful services. + +To register a scoped container, we need to make some changes in the server bootstrapping config code. +First we need to provide a container resolver function. It takes the resolver data (like context) as an argument and should return an instance of the container scoped to the request. + +For simple container libraries we may define it inline, e.g. using `TypeDI`: + +```ts +await buildSchema({ + container: (({ context }: ResolverData) => Container.of(context.requestId)); +}; +``` + +The tricky part is where the `context.requestId` comes from. Unfortunately, we need to provide it manually using hooks that are exposed by HTTP GraphQL middleware like `express-graphql`, `@apollo/server` or `graphql-yoga`. + +For some other advanced libraries, we might need to create an instance of the container, place it in the context object and then retrieve it in the `container` getter function: + +```ts +await buildSchema({ + container: (({ context }: ResolverData) => context.container); +}; +``` + +Example using `TypeDI` and `@apollo/server` with the `context` creation method: + +```ts +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { Container } from "typedi"; + +// Create GraphQL server +const server = new ApolloServer({ + // GraphQL schema + schema, +}); + +// Start server +const { url } = await startStandaloneServer(server, { + listen: { port: 4000 }, + // Provide unique context with 'requestId' for each request + context: async () => { + const requestId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // uuid-like + const container = Container.of(requestId.toString()); // Get scoped container + const context = { requestId, container }; // Create context + container.set("context", context); // Set context or other data in container + + return context; + }, +}); +console.log(`GraphQL server ready at ${url}`); +``` + +We also have to dispose the container after the request has been handled and the response is ready. Otherwise, there would be a huge memory leak as the new instances of services and resolvers have been created for each request but they haven't been cleaned up. + +Apollo Server has a [plugins](https://www.apollographql.com/docs/apollo-server/integrations/plugins) feature that supports [`willSendResponse`](https://www.apollographql.com/docs/apollo-server/integrations/plugins/#willsendresponse) lifecycle event. We can leverage it to clean up the container after handling the request. + +Example using `TypeDI` and `@apollo/server` with plugins approach: + +```ts +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { Container } from "typedi"; + +const server = new ApolloServer({ + // GraphQL schema + schema, + // Create a plugin to allow for disposing the scoped container created for every request + plugins: [ + { + requestDidStart: async () => ({ + async willSendResponse(requestContext) { + // Dispose the scoped container to prevent memory leaks + Container.reset(requestContext.contextValue.requestId.toString()); + + // For developers curiosity purpose, here is the logging of current scoped container instances + // Make multiple parallel requests to see in console how this works + const instancesIds = ((Container as any).instances as ContainerInstance[]).map( + instance => instance.id, + ); + console.log("Instances left in memory: ", instancesIds); + }, + }), + }, + ], +}); +``` + +And basically that's it! The configuration of the container is done and TypeGraphQL will be able to use different instances of resolvers for each request. + +The only thing that's left is the container configuration - we need to check out the docs for our container library (`InversifyJS`, `injection-js`, `TypeDI` or other) to get know how to setup the lifetime of the injectable objects (transient, scoped or singleton). + +> Be aware that some libraries (like `TypeDI`) by default create new instances for every scoped container, so you might experience a **significant increase in memory usage** and some slowing down in query resolving speed, so please be careful with using this feature! + +## Example + +You can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/using-container). + +For a more advanced usage example with scoped containers, check out [advanced example with scoped containers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/using-scoped-container). + +Integration with [TSyringe](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/tsyringe). diff --git a/website/versioned_docs/version-2.0.0-beta.6/examples.md b/website/versioned_docs/version-2.0.0-beta.6/examples.md new file mode 100644 index 000000000..1fd40883a --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.6/examples.md @@ -0,0 +1,53 @@ +--- +title: Examples +sidebar_label: List of examples +id: version-2.0.0-beta.6-examples +original_id: examples +--- + +On the [GitHub repository](https://github.com/MichalLytek/type-graphql) there are a few simple [`examples`](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples) of how to use different `TypeGraphQL` features and how well they integrate with 3rd party libraries. + +To run an example, simply go to the subdirectory (e.g. `cd ./simple-usage`), and then start the server (`npx ts-node ./index.ts`). + +Each subdirectory contains a `examples.graphql` file with predefined GraphQL queries/mutations/subscriptions that you can use in Apollo Studio () and play with them by modifying their shape and data. + +## Basics + +- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/simple-usage) + +## Advanced + +- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/enums-and-unions) +- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/simple-subscriptions) +- [Subscriptions (using Redis) \*\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/redis-subscriptions) +- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/interfaces-inheritance) +- [Extensions (metadata)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/extensions) + +## Features usage + +- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/using-container) + - [Scoped containers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/using-scoped-container) +- [Authorization](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/authorization) +- [Validation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/automatic-validation) + - [Custom validation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/custom-validation) +- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/interfaces-inheritance) +- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/resolvers-inheritance) +- [Generic types](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/generic-types) +- [Mixin classes](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/mixin-classes) +- [Middlewares and Custom Decorators](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/middlewares-custom-decorators) +- [Query complexity](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/query-complexity) + +## 3rd party libs integration + +- [TypeORM (manual, synchronous) \*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/typeorm-basic-usage) +- [TypeORM (automatic, lazy relations) \*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/typeorm-lazy-relations) +- [MikroORM \*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/mikro-orm) +- [Typegoose \*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/typegoose) +- [Apollo Federation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/apollo-federation) +- [Apollo Federation 2](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/apollo-federation-2) +- [Apollo Cache Control](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/apollo-cache) +- [GraphQL Scalars](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/graphql-scalars) +- [TSyringe](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/tsyringe) + +_\* Note that we need to provide the environment variable `DATABASE_URL` with connection parameters to your local database_ \ +_\*\* Note that we need to provide the environment variable `REDIS_URL` with connection parameters to your local Redis instance_ diff --git a/website/versioned_docs/version-2.0.0-beta.6/extensions.md b/website/versioned_docs/version-2.0.0-beta.6/extensions.md new file mode 100644 index 000000000..d34c6840a --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.6/extensions.md @@ -0,0 +1,119 @@ +--- +title: Extensions +id: version-2.0.0-beta.6-extensions +original_id: extensions +--- + +The `graphql-js` library allows for putting arbitrary data into GraphQL types config inside the `extensions` property. +Annotating schema types or fields with a custom metadata, that can be then used at runtime by middlewares or resolvers, is a really powerful and useful feature. + +For such use cases, **TypeGraphQL** provides the `@Extensions` decorator, which adds the data we defined to the `extensions` property of the executable schema for the decorated classes, methods or properties. + +> Be aware that this is a low-level decorator and you generally have to provide your own logic to make use of the `extensions` metadata. + +## Using the `@Extensions` decorator + +Adding extensions to the schema type is as simple as using the `@Extensions` decorator and passing it an object of the custom data we want: + +```ts +@Extensions({ complexity: 2 }) +``` + +We can pass several fields to the decorator: + +```ts +@Extensions({ logMessage: "Restricted access", logLevel: 1 }) +``` + +And we can also decorate a type several times. The snippet below shows that this attaches the exact same extensions data to the schema type as the snippet above: + +```ts +@Extensions({ logMessage: "Restricted access" }) +@Extensions({ logLevel: 1 }) +``` + +If we decorate the same type several times with the same extensions key, the one defined at the bottom takes precedence: + +```ts +@Extensions({ logMessage: "Restricted access" }) +@Extensions({ logMessage: "Another message" }) +``` + +The above usage results in your GraphQL type having a `logMessage: "Another message"` property in its extensions. + +TypeGraphQL classes with the following decorators can be annotated with `@Extensions` decorator: + +- `@ObjectType` +- `@InputType` +- `@Field` +- `@Query` +- `@Mutation` +- `@FieldResolver` + +So the `@Extensions` decorator can be placed over the class property/method or over the type class itself, and multiple times if necessary, depending on what we want to do with the extensions data: + +```ts +@Extensions({ roles: ["USER"] }) +@ObjectType() +class Foo { + @Field() + field: string; +} + +@ObjectType() +class Bar { + @Extensions({ roles: ["USER"] }) + @Field() + field: string; +} + +@ObjectType() +class Bar { + @Extensions({ roles: ["USER"] }) + @Extensions({ visible: false, logMessage: "User accessed restricted field" }) + @Field() + field: string; +} + +@Resolver(of => Foo) +class FooBarResolver { + @Extensions({ roles: ["USER"] }) + @Query() + foobar(@Arg("baz") baz: string): string { + return "foobar"; + } + + @Extensions({ roles: ["ADMIN"] }) + @FieldResolver() + bar(): string { + return "foobar"; + } +} +``` + +## Using the extensions data in runtime + +Once we have decorated the necessary types with extensions, the executable schema will contain the extensions data, and we can make use of it in any way we choose. The most common use will be to read it at runtime in resolvers or middlewares and perform some custom logic there. + +Here is a simple example of a global middleware that will be logging a message on field resolver execution whenever the field is decorated appropriately with `@Extensions`: + +```ts +export class LoggerMiddleware implements MiddlewareInterface { + constructor(private readonly logger: Logger) {} + + use({ info }: ResolverData, next: NextFn) { + // extract `extensions` object from GraphQLResolveInfo object to get the `logMessage` value + const { logMessage } = info.parentType.getFields()[info.fieldName].extensions || {}; + + if (logMessage) { + this.logger.log(logMessage); + } + + return next(); + } +} +``` + +## Examples + +You can see more detailed examples of usage [here](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/extensions). diff --git a/website/versioned_docs/version-2.0.0-beta.6/generic-types.md b/website/versioned_docs/version-2.0.0-beta.6/generic-types.md new file mode 100644 index 000000000..a5ad6539e --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.6/generic-types.md @@ -0,0 +1,169 @@ +--- +title: Generic Types +id: version-2.0.0-beta.6-generic-types +original_id: generic-types +--- + +[Type Inheritance](./inheritance.md) is a great way to reduce code duplication by extracting common fields to the base class. But in some cases, the strict set of fields is not enough because we might need to declare the types of some fields in a more flexible way, like a type parameter (e.g. `items: T[]` in case of a pagination). + +Hence TypeGraphQL also has support for describing generic GraphQL types. + +## How to? + +Unfortunately, the limited reflection capabilities of TypeScript don't allow for combining decorators with standard generic classes. To achieve behavior like that of generic types, we use the same class-creator pattern like the one described in the [Resolvers Inheritance](./inheritance.md) docs. + +### Basic usage + +Start by defining a `PaginatedResponse` function that creates and returns an abstract `PaginatedResponseClass`: + +```ts +export default function PaginatedResponse() { + abstract class PaginatedResponseClass { + // ... + } + return PaginatedResponseClass; +} +``` + +To achieve generic-like behavior, the function has to be generic and take some runtime argument related to the type parameter: + +```ts +export default function PaginatedResponse(TItemClass: ClassType) { + abstract class PaginatedResponseClass { + // ... + } + return PaginatedResponseClass; +} +``` + +Then, add proper decorators to the class which might be `@ObjectType`, `@InterfaceType` or `@InputType`: + +```ts +export default function PaginatedResponse(TItemClass: ClassType) { + @ObjectType() + abstract class PaginatedResponseClass { + // ... + } + return PaginatedResponseClass; +} +``` + +After that, add fields like in a normal class but using the generic type and parameters: + +```ts +export default function PaginatedResponse(TItemClass: ClassType) { + @ObjectType() + abstract class PaginatedResponseClass { + // Runtime argument + @Field(type => [TItemClass]) + // Generic type + items: TItem[]; + + @Field(type => Int) + total: number; + + @Field() + hasMore: boolean; + } + return PaginatedResponseClass; +} +``` + +Finally, use the generic function factory to create a dedicated type class: + +```ts +@ObjectType() +class PaginatedUserResponse extends PaginatedResponse(User) { + // Add more fields or overwrite the existing one's types + @Field(type => [String]) + otherInfo: string[]; +} +``` + +And then use it in our resolvers: + +```ts +@Resolver() +class UserResolver { + @Query() + users(): PaginatedUserResponse { + // Custom business logic, + // depending on underlying data source and libraries + return { + items, + total, + hasMore, + otherInfo, + }; + } +} +``` + +### Complex generic type values + +When we need to provide something different than a class (object type) for the field type, we need to enhance the parameter type signature and provide the needed types. + +Basically, the parameter that the `PaginatedResponse` function accepts is the value we can provide to `@Field` decorator. +So if we want to return an array of strings as the `items` field, we need to add proper types to the function signature, like `GraphQLScalarType` or `String`: + +```ts +export default function PaginatedResponse( + itemsFieldValue: ClassType | GraphQLScalarType | String | Number | Boolean, +) { + @ObjectType() + abstract class PaginatedResponseClass { + @Field(type => [itemsFieldValue]) + items: TItemsFieldValue[]; + + // ... Other fields + } + return PaginatedResponseClass; +} +``` + +And then provide a proper runtime value (like `String`) while creating a proper subtype of generic `PaginatedResponse` object type: + +```ts +@ObjectType() +class PaginatedStringsResponse extends PaginatedResponse(String) { + // ... +} +``` + +### Types factory + +We can also create a generic class without using the `abstract` keyword. +But with this approach, types created with this kind of factory will be registered in the schema, so this way is not recommended to extend the types for adding fields. + +To avoid generating schema errors of duplicated `PaginatedResponseClass` type names, we must provide our own unique, generated type name: + +```ts +export default function PaginatedResponse(TItemClass: ClassType) { + // Provide a unique type name used in schema + @ObjectType(`Paginated${TItemClass.name}Response`) + class PaginatedResponseClass { + // ... + } + return PaginatedResponseClass; +} +``` + +Then, we can store the generated class in a variable and in order to use it both as a runtime object and as a type, we must also create a type for this new class: + +```ts +const PaginatedUserResponse = PaginatedResponse(User); +type PaginatedUserResponse = InstanceType; + +@Resolver() +class UserResolver { + // Provide a runtime type argument to the decorator + @Query(returns => PaginatedUserResponse) + users(): PaginatedUserResponse { + // Same implementation as in the earlier code snippet + } +} +``` + +## Examples + +A more advanced usage example of the generic types feature can be found in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/generic-types). diff --git a/website/versioned_docs/version-2.0.0-beta.6/inheritance.md b/website/versioned_docs/version-2.0.0-beta.6/inheritance.md new file mode 100644 index 000000000..c21d80142 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.6/inheritance.md @@ -0,0 +1,145 @@ +--- +title: Inheritance +id: version-2.0.0-beta.6-inheritance +original_id: inheritance +--- + +The main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes. + +In object-oriented programming it is common to compose classes using inheritance. Hence, TypeGraphQL supports composing type definitions by extending classes. + +## Types inheritance + +One of the most known principles of software development is DRY - Don't Repeat Yourself - which is about avoiding code redundancy. + +While creating a GraphQL API, it's a common pattern to have pagination args in resolvers, like `skip` and `take`. So instead of repeating ourselves, we declare it once: + +```ts +@ArgsType() +class PaginationArgs { + @Field(type => Int) + skip: number = 0; + + @Field(type => Int) + take: number = 25; +} +``` + +and then reuse it everywhere: + +```ts +@ArgsType() +class GetTodosArgs extends PaginationArgs { + @Field() + onlyCompleted: boolean = false; +} +``` + +This technique also works with input type classes, as well as with object type classes: + +```ts +@ObjectType() +class Person { + @Field() + age: number; +} + +@ObjectType() +class Student extends Person { + @Field() + universityName: string; +} +``` + +Note that both the subclass and the parent class must be decorated with the same type of decorator, like `@ObjectType()` in the example `Person -> Student` above. Mixing decorator types across parent and child classes is prohibited and might result in a schema building error, e.g. we can't decorate the subclass with `@ObjectType()` and the parent with `@InputType()`. + +## Resolver Inheritance + +A special kind of inheritance in TypeGraphQL is resolver class inheritance. This pattern allows us e.g. to create a base CRUD resolver class for our resource/entity, so we don't have to repeat common boilerplate code. + +Since we need to generate unique query/mutation names, we have to create a factory function for our base class: + +```ts +function createBaseResolver() { + abstract class BaseResolver {} + + return BaseResolver; +} +``` + +Be aware that with some `tsconfig.json` settings (like `declarations: true`) we might receive a `[ts] Return type of exported function has or is using private name 'BaseResolver'` error - in this case we might need to use `any` as the return type or create a separate class/interface describing the class methods and properties. + +This factory should take a parameter that we can use to generate the query/mutation names, as well as the type that we would return from the resolvers: + +```ts +function createBaseResolver(suffix: string, objectTypeCls: T) { + abstract class BaseResolver {} + + return BaseResolver; +} +``` + +It's very important to mark the `BaseResolver` class using the `@Resolver` decorator: + +```ts +function createBaseResolver(suffix: string, objectTypeCls: T) { + @Resolver() + abstract class BaseResolver {} + + return BaseResolver; +} +``` + +We can then implement the resolver methods as usual. The only difference is that we can use the `name` decorator option for `@Query`, `@Mutation` and `@Subscription` decorators to overwrite the name that will be emitted in schema: + +```ts +function createBaseResolver(suffix: string, objectTypeCls: T) { + @Resolver() + abstract class BaseResolver { + protected items: T[] = []; + + @Query(type => [objectTypeCls], { name: `getAll${suffix}` }) + async getAll(@Arg("first", type => Int) first: number): Promise { + return this.items.slice(0, first); + } + } + + return BaseResolver; +} +``` + +Now we can create a specific resolver class that will extend the base resolver class: + +```ts +const PersonBaseResolver = createBaseResolver("person", Person); + +@Resolver(of => Person) +export class PersonResolver extends PersonBaseResolver { + // ... +} +``` + +We can also add specific queries and mutations in our resolver class, as always: + +```ts +const PersonBaseResolver = createBaseResolver("person", Person); + +@Resolver(of => Person) +export class PersonResolver extends PersonBaseResolver { + @Mutation() + addPerson(@Arg("input") personInput: PersonInput): Person { + this.items.push(personInput); + return personInput; + } +} +``` + +And that's it! We just need to normally register `PersonResolver` in `buildSchema` and the extended resolver will work correctly. + +We must be aware that if we want to overwrite the query/mutation/subscription from the parent resolver class, we need to generate the same schema name (using the `name` decorator option or the class method name). It will overwrite the implementation along with the GraphQL args and return types. If we only provide a different implementation of the inherited method like `getOne`, it won't work. + +## Examples + +More advanced usage examples of type inheritance (and interfaces) can be found in [the example folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/interfaces-inheritance). + +For a more advanced resolver inheritance example, please go to [this example folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/resolvers-inheritance). diff --git a/website/versioned_docs/version-2.0.0-beta.6/interfaces.md b/website/versioned_docs/version-2.0.0-beta.6/interfaces.md new file mode 100644 index 000000000..f4c3a7c7f --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.6/interfaces.md @@ -0,0 +1,258 @@ +--- +title: Interfaces +id: version-2.0.0-beta.6-interfaces +original_id: interfaces +--- + +The main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes. + +In object-oriented programming it is common to create interfaces which describe the contract that classes implementing them must adhere to. Hence, TypeGraphQL supports defining GraphQL interfaces. + +Read more about the GraphQL Interface Type in the [official GraphQL docs](https://graphql.org/learn/schema/#interfaces). + +## Abstract classes + +TypeScript has first class support for interfaces. Unfortunately, they only exist at compile-time, so we can't use them to build GraphQL schema at runtime by using decorators. + +Luckily, we can use an abstract class for this purpose. It behaves almost like an interface as it can't be instantiated but it can be implemented by another class. The only difference is that it just won't prevent developers from implementing a method or initializing a field. So, as long as we treat the abstract class like an interface, we can safely use it. + +## Defining interface type + +How do we create a GraphQL interface definition? We create an abstract class and decorate it with the `@InterfaceType()` decorator. The rest is exactly the same as with object types: we use the `@Field` decorator to declare the shape of the type: + +```ts +@InterfaceType() +abstract class IPerson { + @Field(type => ID) + id: string; + + @Field() + name: string; + + @Field(type => Int) + age: number; +} +``` + +We can then use this interface type class like an interface in the object type class definition: + +```ts +@ObjectType({ implements: IPerson }) +class Person implements IPerson { + id: string; + name: string; + age: number; +} +``` + +The only difference is that we have to let TypeGraphQL know that this `ObjectType` is implementing the `InterfaceType`. We do this by passing the param `({ implements: IPerson })` to the decorator. If we implement multiple interfaces, we pass an array of interfaces like so: `({ implements: [IPerson, IAnimal, IMachine] })`. + +It is also allowed to omit the decorators since the GraphQL types will be copied from the interface definition - this way we won't have to maintain two definitions and solely rely on TypeScript type checking for correct interface implementation. + +We can also extend the base interface type abstract class as well because all the fields are inherited and emitted in schema: + +```ts +@ObjectType({ implements: IPerson }) +class Person extends IPerson { + @Field() + hasKids: boolean; +} +``` + +## Implementing other interfaces + +Since `graphql-js` version `15.0`, it's also possible for interface type to [implement other interface types](https://github.com/graphql/graphql-js/pull/2084). + +To accomplish this, we can just use the same syntax that we utilize for object types - the `implements` decorator option: + +```ts +@InterfaceType() +class Node { + @Field(type => ID) + id: string; +} + +@InterfaceType({ implements: Node }) +class Person extends Node { + @Field() + name: string; + + @Field(type => Int) + age: number; +} +``` + +Also, when we implement the interface that already implements other interface, there's no need to put them all in `implements` array in `@ObjectType` decorator option - only the closest one in the inheritance chain is required, e.g.: + +```ts +@ObjectType({ implements: [Person] }) +class Student extends Person { + @Field() + universityName: string; +} +``` + +This example produces following representation in GraphQL SDL: + +```graphql +interface Node { + id: ID! +} + +interface Person implements Node { + id: ID! + name: String! + age: Int! +} + +type Student implements Node & Person { + id: ID! + name: String! + age: Int! + universityName: String! +} +``` + +## Resolvers and arguments + +What's more, we can define resolvers for the interface fields, using the same syntax we would use when defining one for our object type: + +```ts +@InterfaceType() +abstract class IPerson { + @Field() + firstName: string; + + @Field() + lastName: string; + + @Field() + fullName(): string { + return `${this.firstName} ${this.lastName}`; + } +} +``` + +They're inherited by all the object types that implements this interface type but does not provide their own resolver implementation for those fields. + +Additionally, if we want to declare that the interface accepts some arguments, e.g.: + +```graphql +interface IPerson { + avatar(size: Int!): String! +} +``` + +We can just use `@Arg` or `@Args` decorators as usual: + +```ts +@InterfaceType() +abstract class IPerson { + @Field() + avatar(@Arg("size") size: number): string { + return `http://i.pravatar.cc/${size}`; + } +} +``` + +Unfortunately, TypeScript doesn't allow using decorators on abstract methods. +So if we don't want to provide implementation for that field resolver, only to enforce some signature (args and return type), we have to throw an error inside the body: + +```ts +@InterfaceType() +abstract class IPerson { + @Field() + avatar(@Arg("size") size: number): string { + throw new Error("Method not implemented!"); + } +} +``` + +And then we need to extend the interface class and override the method by providing its body - it is required for all object types that implements that interface type: + +```ts +@ObjectType({ implements: IPerson }) +class Person extends IPerson { + avatar(size: number): string { + return `http://i.pravatar.cc/${size}`; + } +} +``` + +In order to extend the signature by providing additional arguments (like `format`), we need to redeclare the whole field signature: + +```ts +@ObjectType({ implements: IPerson }) +class Person implements IPerson { + @Field() + avatar(@Arg("size") size: number, @Arg("format") format: string): string { + return `http://i.pravatar.cc/${size}.${format}`; + } +} +``` + +Resolvers for interface type fields can be also defined on resolvers classes level, by using the `@FieldResolver` decorator: + +```ts +@Resolver(of => IPerson) +class IPersonResolver { + @FieldResolver() + avatar(@Root() person: IPerson, @Arg("size") size: number): string { + return `http://typegraphql.com/${person.id}/${size}`; + } +} +``` + +## Registering in schema + +By default, if the interface type is explicitly used in schema definition (used as a return type of a query/mutation or as some field type), all object types that implement that interface will be emitted in schema, so we don't need to do anything. + +However, in some cases like the `Node` interface that is used in Relay-based systems, this behavior might be not intended when exposing multiple, separates schemas (like a public and the private ones). + +In this situation, we can provide an `{ autoRegisterImplementations: false }` option to the `@InterfaceType` decorator to prevent emitting all this object types in the schema: + +```ts +@InterfaceType({ autoRegisterImplementations: false }) +abstract class Node { + @Field(type => ID) + id: string; +} +``` + +Then we need to add all the object types (that implement this interface type and which we want to expose in selected schema) to the `orphanedTypes` array option in `buildSchema`: + +```ts +const schema = await buildSchema({ + resolvers, + // Provide orphaned object types + orphanedTypes: [Person, Animal, Recipe], +}); +``` + +Be aware that if the object type class is explicitly used as the GraphQL type (like `Recipe` type as the return type of `addRecipe` mutation), it will be emitted regardless the `orphanedTypes` setting. + +## Resolving Type + +Be aware that when our object type is implementing a GraphQL interface type, **we have to return an instance of the type class** in our resolvers. Otherwise, `graphql-js` will not be able to detect the underlying GraphQL type correctly. + +We can also provide our own `resolveType` function implementation to the `@InterfaceType` options. This way we can return plain objects in resolvers and then determine the returned object type by checking the shape of the data object, the same ways [like in unions](./unions.md), e.g.: + +```ts +@InterfaceType({ + resolveType: value => { + if ("grades" in value) { + return "Student"; // Schema name of type string + } + return Person; // Or object type class + }, +}) +abstract class IPerson { + // ... +} +``` + +However in case of interfaces, it might be a little bit more tricky than with unions, as we might not remember all the object types that implements this particular interface. + +## Examples + +For more advanced usage examples of interfaces (and type inheritance), e.g. with query returning an interface type, go to [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/interfaces-inheritance). diff --git a/website/versioned_docs/version-2.0.0-beta.6/middlewares.md b/website/versioned_docs/version-2.0.0-beta.6/middlewares.md new file mode 100644 index 000000000..6cdff7714 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.6/middlewares.md @@ -0,0 +1,189 @@ +--- +title: Middleware and guards +id: version-2.0.0-beta.6-middlewares +original_id: middlewares +--- + +Middleware are pieces of reusable code that can be easily attached to resolvers and fields. By using middleware we can extract the commonly used code from our resolvers and then declaratively attach it using a decorator or even registering it globally. + +## Creating Middleware + +### What is Middleware? + +Middleware is a very powerful but somewhat complicated feature. Basically, middleware is a function that takes 2 arguments: + +- resolver data - the same as resolvers (`root`, `args`, `context`, `info`) +- the `next` function - used to control the execution of the next middleware and the resolver to which it is attached + +We may be familiar with how middleware works in [`express.js`](https://expressjs.com/en/guide/writing-middleware.html) but TypeGraphQL middleware is inspired by [`koa.js`](http://koajs.com/#application). The difference is that the `next` function returns a promise of the value of subsequent middleware and resolver execution from the stack. + +This makes it easy to perform actions before or after resolver execution. So things like measuring execution time are simple to implement: + +```ts +export const ResolveTime: MiddlewareFn = async ({ info }, next) => { + const start = Date.now(); + await next(); + const resolveTime = Date.now() - start; + console.log(`${info.parentType.name}.${info.fieldName} [${resolveTime} ms]`); +}; +``` + +### Intercepting the execution result + +Middleware also has the ability to intercept the result of a resolver's execution. It's not only able to e.g. create a log but also replace the result with a new value: + +```ts +export const CompetitorInterceptor: MiddlewareFn = async (_, next) => { + const result = await next(); + if (result === "typegql") { + return "type-graphql"; + } + return result; +}; +``` + +It might not seem very useful from the perspective of this library's users but this feature was mainly introduced for plugin systems and 3rd-party library integration. Thanks to this, it's possible to e.g. wrap the returned object with a lazy-relation wrapper that automatically fetches relations from a database on demand under the hood. + +### Simple Middleware + +If we only want to do something before an action, like log the access to the resolver, we can just place the `return next()` statement at the end of our middleware: + +```ts +const LogAccess: MiddlewareFn = ({ context, info }, next) => { + const username: string = context.username || "guest"; + console.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`); + return next(); +}; +``` + +### Guards + +Middleware can also break the middleware stack by not calling the `next` function. This way, the result returned from the middleware will be used instead of calling the resolver and returning it's result. + +We can also throw an error in the middleware if the execution must be terminated and an error returned to the user, e.g. when resolver arguments are incorrect. + +This way we can create a guard that blocks access to the resolver and prevents execution or any data return. + +```ts +export const CompetitorDetector: MiddlewareFn = async ({ args }, next) => { + if (args.frameworkName === "type-graphql") { + return "TypeGraphQL"; + } + if (args.frameworkName === "typegql") { + throw new Error("Competitive framework detected!"); + } + return next(); +}; +``` + +### Reusable Middleware + +Sometimes middleware has to be configurable, just like we pass a `roles` array to the [`@Authorized()` decorator](./authorization.md). In this case, we should create a simple middleware factory - a function that takes our configuration as a parameter and returns a middleware that uses the provided value. + +```ts +export function NumberInterceptor(minValue: number): MiddlewareFn { + return async (_, next) => { + const result = await next(); + // Hide values below minValue + if (typeof result === "number" && result < minValue) { + return null; + } + return result; + }; +} +``` + +Remember to call this middleware with an argument, e.g. `NumberInterceptor(3.0)`, when attaching it to a resolver! + +### Error Interceptors + +Middleware can also catch errors that were thrown during execution. This way, they can easily be logged and even filtered for info that can't be returned to the user: + +```ts +export const ErrorInterceptor: MiddlewareFn = async ({ context, info }, next) => { + try { + return await next(); + } catch (err) { + // Write error to file log + fileLog.write(err, context, info); + + // Hide errors from db like printing sql query + if (someCondition(err)) { + throw new Error("Unknown error occurred!"); + } + + // Rethrow the error + throw err; + } +}; +``` + +### Class-based Middleware + +Sometimes our middleware logic can be a bit complicated - it may communicate with a database, write logs to file, etc., so we might want to test it. In that case we create class middleware that is able to benefit from [dependency injection](./dependency-injection.md) and easily mock a file logger or a database repository. + +To accomplish this, we implement a `MiddlewareInterface`. Our class must have the `use` method that conforms with the `MiddlewareFn` signature. Below we can see how the previously defined `LogAccess` middleware looks after the transformation: + +```ts +export class LogAccess implements MiddlewareInterface { + constructor(private readonly logger: Logger) {} + + async use({ context, info }: ResolverData, next: NextFn) { + const username: string = context.username || "guest"; + this.logger.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`); + return next(); + } +} +``` + +## How to use + +### Attaching Middleware + +To attach middleware to a resolver, place the `@UseMiddleware()` decorator above the field or resolver declaration. It accepts an array of middleware that will be called in the provided order. We can also pass them without an array as it supports [rest parameters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters): + +```ts +@Resolver() +export class RecipeResolver { + @Query() + @UseMiddleware(ResolveTime, LogAccess) + randomValue(): number { + return Math.random(); + } +} +``` + +We can also attach the middleware to the `ObjectType` fields, the same way as with the [`@Authorized()` decorator](./authorization.md). + +```ts +@ObjectType() +export class Recipe { + @Field() + title: string; + + @Field(type => [Int]) + @UseMiddleware(LogAccess) + ratings: number[]; +} +``` + +### Global Middleware + +However, for common middleware like measuring resolve time or catching errors, it might be annoying to place a `@UseMiddleware(ResolveTime)` decorator on every field/resolver. + +Hence, in TypeGraphQL we can also register a global middleware that will be called for each query, mutation, subscription and field resolver. For this, we use the `globalMiddlewares` property of the `buildSchema` configuration object: + +```ts +const schema = await buildSchema({ + resolvers: [RecipeResolver], + globalMiddlewares: [ErrorInterceptor, ResolveTime], +}); +``` + +### Custom Decorators + +If we want to use middlewares with a more descriptive and declarative API, we can also create a custom method decorators. See how to do this in [custom decorators docs](./custom-decorators.md#method-decorators). + +## Example + +See how different kinds of middlewares work in the [middlewares and custom decorators example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/middlewares-custom-decorators). diff --git a/website/versioned_docs/version-2.0.0-beta.6/resolvers.md b/website/versioned_docs/version-2.0.0-beta.6/resolvers.md new file mode 100644 index 000000000..55f62c2b3 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.6/resolvers.md @@ -0,0 +1,352 @@ +--- +title: Resolvers +id: version-2.0.0-beta.6-resolvers +original_id: resolvers +--- + +Besides [declaring GraphQL's object types](./types-and-fields.md), TypeGraphQL allows us to easily create queries, mutations and field resolvers - like normal class methods, similar to REST controllers in frameworks like Java `Spring`, .NET `Web API` or TypeScript [`routing-controllers`](https://github.com/typestack/routing-controllers). + +## Queries and Mutations + +### Resolver classes + +First we create the resolver class and annotate it with the `@Resolver()` decorator. This class will behave like a controller from classic REST frameworks: + +```ts +@Resolver() +class RecipeResolver {} +``` + +We can use a DI framework (as described in the [dependency injection docs](./dependency-injection.md)) to inject class dependencies (like services or repositories) or to store data inside the resolver class - it's guaranteed to be a single instance per app. + +```ts +@Resolver() +class RecipeResolver { + private recipesCollection: Recipe[] = []; +} +``` + +Then we can create class methods which will handle queries and mutations. For example, let's add the `recipes` query to return a collection of all recipes: + +```ts +@Resolver() +class RecipeResolver { + private recipesCollection: Recipe[] = []; + + async recipes() { + // Fake async + return await this.recipesCollection; + } +} +``` + +We also need to do two things. +The first is to add the `@Query` decorator, which marks the class method as a GraphQL query. +The second is to provide the return type. Since the method is async, the reflection metadata system shows the return type as a `Promise`, so we have to add the decorator's parameter as `returns => [Recipe]` to declare it resolves to an array of `Recipe` object types. + +```ts +@Resolver() +class RecipeResolver { + private recipesCollection: Recipe[] = []; + + @Query(returns => [Recipe]) + async recipes() { + return await this.recipesCollection; + } +} +``` + +### Arguments + +Usually, queries have some arguments - it might be the id of a resource, a search phrase or pagination settings. TypeGraphQL allows you to define arguments in two ways. + +First is the inline method using the `@Arg()` decorator. The drawback is the need to repeating the argument name (due to a limitation of the reflection system) in the decorator parameter. As we can see below, we can also pass a `defaultValue` option that will be reflected in the GraphQL schema. + +```ts +@Resolver() +class RecipeResolver { + // ... + @Query(returns => [Recipe]) + async recipes( + @Arg("servings", { defaultValue: 2 }) servings: number, + @Arg("title", { nullable: true }) title?: string, + ): Promise { + // ... + } +} +``` + +This works well when there are 2 - 3 args. But when you have many more, the resolver's method definitions become bloated. In this case we can use a class definition to describe the arguments. It looks like the object type class but it has the `@ArgsType()` decorator on top. + +```ts +@ArgsType() +class GetRecipesArgs { + @Field(type => Int, { nullable: true }) + skip?: number; + + @Field(type => Int, { nullable: true }) + take?: number; + + @Field({ nullable: true }) + title?: string; +} +``` + +We can define default values for optional fields in the `@Field()` decorator using the `defaultValue` option or by using a property initializer - in both cases TypeGraphQL will reflect this in the schema by setting the default value, so users will be able to omit those args while sending a query. + +> Be aware that `defaultValue` works only for input args and fields, like `@Arg`, `@ArgsType` and `@InputType`. +> Setting `defaultValue` does not affect `@ObjectType` or `@InterfaceType` fields as they are for output purposes only. + +Also, this way of declaring arguments allows you to perform validation. You can find more details about this feature in the [validation docs](./validation.md). + +We can also define helper fields and methods for our args or input classes. But be aware that **defining constructors is strictly forbidden** and we shouldn't use them there, as TypeGraphQL creates instances of args and input classes under the hood by itself. + +```ts +import { Min, Max } from "class-validator"; + +@ArgsType() +class GetRecipesArgs { + @Field(type => Int, { defaultValue: 0 }) + @Min(0) + skip: number; + + @Field(type => Int) + @Min(1) + @Max(50) + take = 25; + + @Field({ nullable: true }) + title?: string; + + // Helpers - index calculations + get startIndex(): number { + return this.skip; + } + get endIndex(): number { + return this.skip + this.take; + } +} +``` + +Then all that is left to do is use the args class as the type of the method parameter. +We can use the destructuring syntax to gain access to single arguments as variables, instead of the reference to the whole args object. + +```ts +@Resolver() +class RecipeResolver { + // ... + @Query(returns => [Recipe]) + async recipes(@Args() { title, startIndex, endIndex }: GetRecipesArgs) { + // Example implementation + let recipes = this.recipesCollection; + if (title) { + recipes = recipes.filter(recipe => recipe.title === title); + } + return recipes.slice(startIndex, endIndex); + } +} +``` + +This declaration will result in the following part of the schema in SDL: + +```graphql +type Query { + recipes(skip: Int = 0, take: Int = 25, title: String): [Recipe!] +} +``` + +### Input types + +GraphQL mutations can be similarly created: Declare the class method, use the `@Mutation` decorator, create arguments, provide a return type (if needed) etc. But for mutations we usually use `input` types, hence TypeGraphQL allows us to create inputs in the same way as [object types](./types-and-fields.md) but by using the `@InputType()` decorator: + +```ts +@InputType() +class AddRecipeInput {} +``` + +To ensure we don't accidentally change the property type we leverage the TypeScript type checking system by implementing the `Partial` type: + +```ts +@InputType() +class AddRecipeInput implements Partial {} +``` + +We then declare any input fields we need, using the `@Field()` decorator: + +```ts +@InputType({ description: "New recipe data" }) +class AddRecipeInput implements Partial { + @Field() + title: string; + + @Field({ nullable: true }) + description?: string; +} +``` + +After that we can use the `AddRecipeInput` type in our mutation. We can do this inline (using the `@Arg()` decorator) or as a field of the args class like in the query example above. + +We may also need access to the context. To achieve this we use the `@Ctx()` decorator with the optional user-defined `Context` interface: + +```ts +@Resolver() +class RecipeResolver { + // ... + @Mutation() + addRecipe(@Arg("data") newRecipeData: AddRecipeInput, @Ctx() ctx: Context): Recipe { + // Example implementation + const recipe = RecipesUtils.create(newRecipeData, ctx.user); + this.recipesCollection.push(recipe); + return recipe; + } +} +``` + +Because our method is synchronous and explicitly returns `Recipe`, we can omit the `@Mutation()` type annotation. + +This declaration will result in the following part of the schema in SDL: + +```graphql +input AddRecipeInput { + title: String! + description: String +} +``` + +```graphql +type Mutation { + addRecipe(data: AddRecipeInput!): Recipe! +} +``` + +By using parameter decorators, we can get rid of unnecessary parameters (like `root`) that bloat our method definition and have to be ignored by prefixing the parameter name with `_`. Also, we can achieve a clean separation between GraphQL and our business code by using decorators, so our resolvers and their methods behave just like services which can be easily unit-tested. + +## Field resolvers + +Queries and mutations are not the only type of resolvers. We often create object type field resolvers (e.g. when a `user` type has a `posts` field) which we have to resolve by fetching relational data from the database. + +Field resolvers in TypeGraphQL are very similar to queries and mutations - we create them as a method on the resolver class but with a few modifications. First we declare which object type fields we are resolving by providing the type to the `@Resolver` decorator: + +```ts +@Resolver(of => Recipe) +class RecipeResolver { + // Queries and mutations +} +``` + +Then we create a class method that will become the field resolver. +In our example we have the `averageRating` field in the `Recipe` object type that should calculate the average from the `ratings` array. + +```ts +@Resolver(of => Recipe) +class RecipeResolver { + // Queries and mutations + + averageRating(recipe: Recipe) { + // ... + } +} +``` + +We then mark the method as a field resolver with the `@FieldResolver()` decorator. Since we've already defined the field type in the `Recipe` class definition, there's no need to redefine it. We also decorate the method parameters with the `@Root` decorator in order to inject the recipe object. + +```ts +@Resolver(of => Recipe) +class RecipeResolver { + // Queries and mutations + + @FieldResolver() + averageRating(@Root() recipe: Recipe) { + // ... + } +} +``` + +For enhanced type safety we can implement the `ResolverInterface` interface. +It's a small helper that checks if the return type of the field resolver methods, like `averageRating(...)`, matches the `averageRating` property of the `Recipe` class and whether the first parameter of the method is the actual object type (`Recipe` class). + +```ts +@Resolver(of => Recipe) +class RecipeResolver implements ResolverInterface { + // Queries and mutations + + @FieldResolver() + averageRating(@Root() recipe: Recipe) { + // ... + } +} +``` + +Here is the full implementation of the sample `averageRating` field resolver: + +```ts +@Resolver(of => Recipe) +class RecipeResolver implements ResolverInterface { + // Queries and mutations + + @FieldResolver() + averageRating(@Root() recipe: Recipe) { + const ratingsSum = recipe.ratings.reduce((a, b) => a + b, 0); + return recipe.ratings.length ? ratingsSum / recipe.ratings.length : null; + } +} +``` + +For simple resolvers like `averageRating` or deprecated fields that behave like aliases, you can create field resolvers inline in the object type class definition: + +```ts +@ObjectType() +class Recipe { + @Field() + title: string; + + @Field({ deprecationReason: "Use `title` instead" }) + get name(): string { + return this.title; + } + + @Field(type => [Rate]) + ratings: Rate[]; + + @Field(type => Float, { nullable: true }) + averageRating(@Arg("since") sinceDate: Date): number | null { + const ratings = this.ratings.filter(rate => rate.date > sinceDate); + if (!ratings.length) return null; + + const ratingsSum = ratings.reduce((a, b) => a + b, 0); + return ratingsSum / ratings.length; + } +} +``` + +However, if the code is more complicated and has side effects (i.e. api calls, fetching data from a databases), a resolver class method should be used instead. This way we can leverage the dependency injection mechanism, which is really helpful in testing. For example: + +```ts +import { Repository } from "typeorm"; + +@Resolver(of => Recipe) +class RecipeResolver implements ResolverInterface { + constructor( + // Dependency injection + private readonly userRepository: Repository, + ) {} + + @FieldResolver() + async author(@Root() recipe: Recipe) { + const author = await this.userRepository.findById(recipe.userId); + if (!author) throw new SomethingWentWrongError(); + return author; + } +} +``` + +Note that if a field name of a field resolver doesn't exist in the resolver object type, it will create a field in the schema with this name. This feature is useful when the field is purely calculable (eg. `averageRating` from `ratings` array) and to avoid polluting the class signature. + +## Resolver Inheritance + +Resolver class `inheritance` is an advanced topic covered in the [resolver inheritance docs](./inheritance.md#resolvers-inheritance). + +## Examples + +These code samples are just made up for tutorial purposes. +You can find more advanced, real examples in the [examples folder on the repository](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples). diff --git a/website/versioned_docs/version-2.0.0-beta.6/subscriptions.md b/website/versioned_docs/version-2.0.0-beta.6/subscriptions.md new file mode 100644 index 000000000..b77525b28 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.6/subscriptions.md @@ -0,0 +1,214 @@ +--- +title: Subscriptions +id: version-2.0.0-beta.6-subscriptions +original_id: subscriptions +--- + +GraphQL can be used to perform reads with queries and writes with mutations. +However, oftentimes clients want to get updates pushed to them from the server when data they care about changes. +To support that, GraphQL has a third operation: subscription. TypeGraphQL of course has great support for subscription, using the [`@graphql-yoga/subscriptions`](https://the-guild.dev/graphql/yoga-server/docs/features/subscriptions) package created by [`The Guild`](https://the-guild.dev/). + +## Creating Subscriptions + +Subscription resolvers are similar to [queries and mutation resolvers](./resolvers.md) but slightly more complicated. + +First we create a normal class method as always, but this time annotated with the `@Subscription()` decorator. + +```ts +class SampleResolver { + // ... + @Subscription() + newNotification(): Notification { + // ... + } +} +``` + +Then we have to provide the topics we wish to subscribe to. This can be a single topic string, an array of topics or a function to dynamically create a topic based on subscription arguments passed to the query. We can also use TypeScript enums for enhanced type safety. + +```ts +class SampleResolver { + // ... + @Subscription({ + topics: "NOTIFICATIONS", // Single topic + topics: ["NOTIFICATIONS", "ERRORS"] // Or topics array + topics: ({ args, context }) => args.topic // Or dynamic topic function + }) + newNotification(): Notification { + // ... + } +} +``` + +We can also provide the `filter` option to decide which topic events should trigger our subscription. +This function should return a `boolean` or `Promise` type. + +```ts +class SampleResolver { + // ... + @Subscription({ + topics: "NOTIFICATIONS", + filter: ({ payload, args }) => args.priorities.includes(payload.priority), + }) + newNotification(): Notification { + // ... + } +} +``` + +We can also provide a custom subscription logic which might be useful, e.g. if we want to use the Prisma subscription functionality or something similar. + +All we need to do is to use the `subscribe` option which should be a function that returns an `AsyncIterable` or a `Promise`. Example using Prisma 1 subscription feature: + +```ts +class SampleResolver { + // ... + @Subscription({ + subscribe: (root, args, context, info) => { + return context.prisma.$subscribe.users({ mutation_in: [args.mutationType] }); + }, + }) + newNotification(): Notification { + // ... + } +} +``` + +> Be aware that we can't mix the `subscribe` option with the `topics` and `filter` options. If the filtering is still needed, we can use the [`filter` and `map` helpers](https://the-guild.dev/graphql/yoga-server/docs/features/subscriptions#filter-and-map-values) from the `@graphql-yoga/subscriptions` package. + +Now we can implement the subscription resolver. It will receive the payload from a triggered topic of the pubsub system using the `@Root()` decorator. There, we can transform it to the returned shape. + +```ts +class SampleResolver { + // ... + @Subscription({ + topics: "NOTIFICATIONS", + filter: ({ payload, args }) => args.priorities.includes(payload.priority), + }) + newNotification( + @Root() notificationPayload: NotificationPayload, + @Args() args: NewNotificationsArgs, + ): Notification { + return { + ...notificationPayload, + date: new Date(), + }; + } +} +``` + +## Triggering subscription topics + +Ok, we've created subscriptions, but what is the `pubsub` system and how do we trigger topics? + +They might be triggered from external sources like a database but also in mutations, +e.g. when we modify some resource that clients want to receive notifications about when it changes. + +So, let us assume we have this mutation for adding a new comment: + +```ts +class SampleResolver { + // ... + @Mutation(returns => Boolean) + async addNewComment(@Arg("comment") input: CommentInput) { + const comment = this.commentsService.createNew(input); + await this.commentsRepository.save(comment); + return true; + } +} +``` + +First, we need to create the `PubSub` instance. In most cases, we call `createPubSub()` function from `@graphql-yoga/subscriptions` package. Optionally, we can define the used topics and payload type using the type argument, e.g.: + +```ts +import { createPubSub } from "@graphql-yoga/subscriptions"; + +export const pubSub = createPubSub<{ + NOTIFICATIONS: [NotificationPayload]; + DYNAMIC_ID_TOPIC: [number, NotificationPayload]; +}>(); +``` + +Then, we need to register the `PubSub` instance in the `buildSchema()` function options: + +```ts +import { buildSchema } from "type-graphql"; +import { pubSub } from "./pubsub"; + +const schema = await buildSchema({ + resolver, + pubSub, +}); +``` + +Finally, we can use the created `PubSub` instance to trigger the topics and send the payload to all topic subscribers: + +```ts +import { pubSub } from "./pubsub"; + +class SampleResolver { + // ... + @Mutation(returns => Boolean) + async addNewComment(@Arg("comment") input: CommentInput, @PubSub() pubSub: PubSubEngine) { + const comment = this.commentsService.createNew(input); + await this.commentsRepository.save(comment); + // Trigger subscriptions topics + const payload: NotificationPayload = { message: input.content }; + pubSub.publish("NOTIFICATIONS", payload); + return true; + } +} +``` + +And that's it! Now all subscriptions attached to the `NOTIFICATIONS` topic will be triggered when performing the `addNewComment` mutation. + +## Topic with dynamic ID + +The idea of this feature is taken from the `@graphql-yoga/subscriptions` that is used under the hood. +Basically, sometimes you only want to emit and listen for events for a specific entity (e.g. user or product). Dynamic topic ID lets you declare topics scoped to a special identifier, e.g.: + +```ts +@Resolver() +class NotificationResolver { + @Subscription({ + topics: "NOTIFICATIONS", + topicId: ({ context }) => context.userId, + }) + newNotification(@Root() { message }: NotificationPayload): Notification { + return { message, date: new Date() }; + } +} +``` + +Then in your mutation or services, you need to pass the topic id as the second parameter: + +```ts +pubSub.publish("NOTIFICATIONS", userId, { id, message }); +``` + +> Be aware that this feature must be supported by the pubsub system of your choice. +> If you decide to use something different than `createPubSub()` from `@graphql-yoga/subscriptions`, the second argument might be treated as a payload, not dynamic topic id. + +## Using a custom PubSub system + +While TypeGraphQL uses the `@graphql-yoga/subscriptions` package under the hood to handle subscription, there's no requirement to use that implementation of `PubSub`. + +In fact, you can use any pubsub system you want, not only the `graphql-yoga` one. +The only requirement is to comply with the exported `PubSub` interface - having proper `.subscribe()` and `.publish()` methods. + +This is especially helpful for production usage, where we can't rely on the in-memory event emitter, so that we [use distributed pubsub](https://the-guild.dev/graphql/yoga-server/docs/features/subscriptions#distributed-pubsub-for-production). + +## Creating a Subscription Server + +The [bootstrap guide](./bootstrap.md) and all the earlier examples used [`apollo-server`](https://github.com/apollographql/apollo-server) to create an HTTP endpoint for our GraphQL API. + +However, beginning in Apollo Server 3, subscriptions are not supported by the "batteries-included" apollo-server package. To enable subscriptions, you need to follow the guide on their docs page: + + +## Examples + +See how subscriptions work in a [simple example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/simple-subscriptions). You can see there, how simple is setting up GraphQL subscriptions using `graphql-yoga` package. + + + diff --git a/website/versioned_docs/version-2.0.0-beta.6/unions.md b/website/versioned_docs/version-2.0.0-beta.6/unions.md new file mode 100644 index 000000000..c8b156894 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.6/unions.md @@ -0,0 +1,109 @@ +--- +title: Unions +id: version-2.0.0-beta.6-unions +original_id: unions +--- + +Sometimes our API has to be flexible and return a type that is not specific but one from a range of possible types. An example might be a movie site's search functionality: using the provided phrase we search the database for movies but also actors. So the query has to return a list of `Movie` or `Actor` types. + +Read more about the GraphQL Union Type in the [official GraphQL docs](http://graphql.org/learn/schema/#union-types). + +## Usage + +Let's start by creating the object types from the example above: + +```ts +@ObjectType() +class Movie { + @Field() + name: string; + + @Field() + rating: number; +} +``` + +```ts +@ObjectType() +class Actor { + @Field() + name: string; + + @Field(type => Int) + age: number; +} +``` + +Now let's create an union type from the object types above - the rarely seen `[ ] as const` syntax is to inform TypeScript compiler that it's a tuple, which allows for better TS union type inference: + +```ts +import { createUnionType } from "type-graphql"; + +const SearchResultUnion = createUnionType({ + name: "SearchResult", // Name of the GraphQL union + types: () => [Movie, Actor] as const, // function that returns tuple of object types classes +}); +``` + +Then we can use the union type in the query by providing the `SearchResultUnion` value in the `@Query` decorator return type annotation. +Notice, that we have to explicitly use the decorator return type annotation due to TypeScript's reflection limitations. +For TypeScript compile-time type safety we can also use `typeof SearchResultUnion` which is equal to type `Movie | Actor`. + +```ts +@Resolver() +class SearchResolver { + @Query(returns => [SearchResultUnion]) + async search(@Arg("phrase") phrase: string): Promise> { + const movies = await Movies.findAll(phrase); + const actors = await Actors.findAll(phrase); + + return [...movies, ...actors]; + } +} +``` + +## Resolving Type + +Be aware that when the query/mutation return type (or field type) is a union, we have to return a specific instance of the object type class. Otherwise, `graphql-js` will not be able to detect the underlying GraphQL type correctly when we use plain JS objects. + +However, we can also provide our own `resolveType` function implementation to the `createUnionType` options. This way we can return plain objects in resolvers and then determine the returned object type by checking the shape of the data object, e.g.: + +```ts +const SearchResultUnion = createUnionType({ + name: "SearchResult", + types: () => [Movie, Actor] as const, + // Implementation of detecting returned object type + resolveType: value => { + if ("rating" in value) { + return Movie; // Return object type class (the one with `@ObjectType()`) + } + if ("age" in value) { + return "Actor"; // Or the schema name of the type as a string + } + return undefined; + }, +}); +``` + +**Et VoilΓ !** We can now build the schema and make the example query πŸ˜‰ + +```graphql +query { + search(phrase: "Holmes") { + ... on Actor { + # Maybe Katie Holmes? + name + age + } + ... on Movie { + # For sure Sherlock Holmes! + name + rating + } + } +} +``` + +## Examples + +More advanced usage examples of unions (and enums) are located in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/enums-and-unions). diff --git a/website/versioned_docs/version-2.0.0-beta.6/validation.md b/website/versioned_docs/version-2.0.0-beta.6/validation.md new file mode 100644 index 000000000..ee68d5b74 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-beta.6/validation.md @@ -0,0 +1,258 @@ +--- +title: Argument and Input validation +sidebar_label: Validation +id: version-2.0.0-beta.6-validation +original_id: validation +--- + +## Scalars + +The standard way to ensure that inputs and arguments are correct, such as an `email` field that really contains a proper e-mail address, is to use [custom scalars](./scalars.md) e.g. `GraphQLEmail` from [`graphql-custom-types`](https://github.com/stylesuxx/graphql-custom-types). However, creating scalars for all single cases of data types (credit card number, base64, IP, URL) might be cumbersome. + +That's why TypeGraphQL has built-in support for argument and input validation. +By default, we can use the [`class-validator`](https://github.com/typestack/class-validator) library and easily declare the requirements for incoming data (e.g. a number is in the range 0-255 or a password that is longer than 8 characters) thanks to the awesomeness of decorators. + +We can also use other libraries or our own custom solution, as described in [custom validators](#custom-validator) section. + +## `class-validator` + +### How to use + +First, we need to install the `class-validator` package: + +```sh +npm install class-validator +``` + +Then we decorate the input/arguments class with the appropriate decorators from `class-validator`. +So we take this: + +```ts +@InputType() +export class RecipeInput { + @Field() + title: string; + + @Field({ nullable: true }) + description?: string; +} +``` + +...and turn it into this: + +```ts +import { MaxLength, Length } from "class-validator"; + +@InputType() +export class RecipeInput { + @Field() + @MaxLength(30) + title: string; + + @Field({ nullable: true }) + @Length(30, 255) + description?: string; +} +``` + +Then we need to enable the auto-validate feature (as it's disabled by default) by simply setting `validate: true` in `buildSchema` options, e.g.: + +```ts +const schema = await buildSchema({ + resolvers: [RecipeResolver], + validate: true, // Enable 'class-validator' integration +}); +``` + +And that's it! πŸ˜‰ + +TypeGraphQL will automatically validate our inputs and arguments based on the definitions: + +```ts +@Resolver(of => Recipe) +export class RecipeResolver { + @Mutation(returns => Recipe) + async addRecipe(@Arg("input") recipeInput: RecipeInput): Promise { + // 100% sure that the input is correct + console.assert(recipeInput.title.length <= 30); + console.assert(recipeInput.description.length >= 30); + console.assert(recipeInput.description.length <= 255); + } +} +``` + +Of course, [there are many more decorators](https://github.com/typestack/class-validator#validation-decorators) we have access to, not just the simple `@Length` decorator used in the example above, so take a look at the `class-validator` documentation. + +This feature is enabled by default. However, we can disable it if we must: + +```ts +const schema = await buildSchema({ + resolvers: [RecipeResolver], + validate: false, // Disable automatic validation or pass the default config object +}); +``` + +And we can still enable it per resolver's argument if we need to: + +```ts +class RecipeResolver { + @Mutation(returns => Recipe) + async addRecipe(@Arg("input", { validate: true }) recipeInput: RecipeInput) { + // ... + } +} +``` + +The `ValidatorOptions` object used for setting features like [validation groups](https://github.com/typestack/class-validator#validation-groups) can also be passed: + +```ts +class RecipeResolver { + @Mutation(returns => Recipe) + async addRecipe( + @Arg("input", { validate: { groups: ["admin"] } }) + recipeInput: RecipeInput, + ) { + // ... + } +} +``` + +Note that by default, the `skipMissingProperties` setting of the `class-validator` is set to `true` because GraphQL will independently check whether the params/fields exist or not. +Same goes to `forbidUnknownValues` setting which is set to `false` because the GraphQL runtime checks for additional data, not described in schema. + +GraphQL will also check whether the fields have correct types (String, Int, Float, Boolean, etc.) so we don't have to use the `@IsOptional`, `@Allow`, `@IsString` or the `@IsInt` decorators at all! + +However, when using nested input or arrays, we always have to use [`@ValidateNested()` decorator](https://github.com/typestack/class-validator#validating-nested-objects) or [`{ each: true }` option](https://github.com/typestack/class-validator#validating-arrays) to make nested validation work properly. + +### Response to the Client + +When a client sends incorrect data to the server: + +```graphql +mutation ValidationMutation { + addRecipe( + input: { + # Too long! + title: "Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet" + } + ) { + title + creationDate + } +} +``` + +the [`ArgumentValidationError`](https://github.com/MichalLytek/type-graphql/blob/master/src/errors/ArgumentValidationError.ts) will be thrown. + +By default, the `apollo-server` package from the [bootstrap guide](./bootstrap.md) will format the error to match the `GraphQLFormattedError` interface. So when the `ArgumentValidationError` occurs, the client will receive this JSON with a nice `validationErrors` property inside of `extensions.exception`: + +```json +{ + "errors": [ + { + "message": "Argument Validation Error", + "locations": [ + { + "line": 2, + "column": 3 + } + ], + "path": ["addRecipe"], + "extensions": { + "code": "INTERNAL_SERVER_ERROR", + "exception": { + "validationErrors": [ + { + "target": { + "title": "Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet" + }, + "value": "Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet", + "property": "title", + "children": [], + "constraints": { + "maxLength": "title must be shorter than or equal to 30 characters" + } + } + ], + "stacktrace": [ + "Error: Argument Validation Error", + " at Object. (/type-graphql/src/resolvers/validate-arg.ts:29:11)", + " at Generator.throw ()", + " at rejected (/type-graphql/node_modules/tslib/tslib.js:105:69)", + " at processTicksAndRejections (internal/process/next_tick.js:81:5)" + ] + } + } + } + ], + "data": null +} +``` + +Of course we can also create our own custom implementation of the `formatError` function provided in the `ApolloServer` config options which will transform the `GraphQLError` with a `ValidationError` array in the desired output format (e.g. `extensions.code = "ARGUMENT_VALIDATION_ERROR"`). + +### Automatic Validation Example + +To see how this works, check out the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/automatic-validation). + +### Caveats + +Even if we don't use the validation feature (and we have provided `{ validate: false }` option to `buildSchema`), we still need to have `class-validator` installed as a dev dependency in order to compile our app without errors using `tsc`. + +An alternative solution that allows to completely get rid off big `class-validator` from our project's `node_modules` folder is to suppress the `error TS2307: Cannot find module 'class-validator'` TS error by providing `"skipLibCheck": true` setting in `tsconfig.json`. + +## Custom validator + +We can also use other libraries than `class-validator` together with TypeGraphQL. + +To integrate it, all we need to do is to provide a custom function. +It receives three parameters: + +- `argValue` which is the injected value of `@Arg()` or `@Args()` +- `argType` which is a runtime type information (e.g. `String` or `RecipeInput`) +- `resolverData` which holds the resolver execution context, described as generic type `ResolverData` + +This function can be an async function and should return nothing (`void`) when validation passes, or throw an error when validation fails. +So be aware of this while trying to wrap another library in `validateFn` function for TypeGraphQL. + +Then we provide this function as a `validateFn` option in `buildSchema`. +Example using [decorators library for Joi validators (`joiful`)](https://github.com/joiful-ts/joiful): + +```ts +const schema = await buildSchema({ + // ... + validateFn: argValue => { + // Call joiful validate + const { error } = joiful.validate(argValue); + if (error) { + // Throw error on failed validation + throw error; + } + }, +}); +``` + +The `validateFn` option is also supported as a `@Arg()` or `@Args()` decorator option, e.g.: + +```ts +@Resolver() +class SampleResolver { + @Query() + sampleQuery( + @Arg("sampleArg", { + validateFn: (argValue, argType) => { + // Do something here with arg value and type... + }, + }) + sampleArg: string, + ): string { + // ... + } +} +``` + +> Be aware that when using custom validator, the error won't be wrapped with `ArgumentValidationError` like for the built-in `class-validator` validation. + +### Custom Validation Example + +To see how this works, check out the [simple custom validation integration example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-beta.6/examples/custom-validation). diff --git a/website/versioned_docs/version-2.0.0-rc.1/authorization.md b/website/versioned_docs/version-2.0.0-rc.1/authorization.md new file mode 100644 index 000000000..2741413e4 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-rc.1/authorization.md @@ -0,0 +1,195 @@ +--- +title: Authorization +id: version-2.0.0-rc.1-authorization +original_id: authorization +--- + +Authorization is a core feature used in almost all APIs. Sometimes we want to restrict data access or actions for a specific group of users. + +In express.js (and other Node.js frameworks) we use middleware for this, like `passport.js` or the custom ones. However, in GraphQL's resolver architecture we don't have middleware so we have to imperatively call the auth checking function and manually pass context data to each resolver, which might be a bit tedious. + +That's why authorization is a first-class feature in `TypeGraphQL`! + +## How to use + +First, we need to use the `@Authorized` decorator as a guard on a field, query or mutation. +Example object type field guards: + +```ts +@ObjectType() +class MyObject { + @Field() + publicField: string; + + @Authorized() + @Field() + authorizedField: string; + + @Authorized("ADMIN") + @Field() + adminField: string; + + @Authorized(["ADMIN", "MODERATOR"]) + @Field({ nullable: true }) + hiddenField?: string; +} +``` + +We can leave the `@Authorized` decorator brackets empty or we can specify the role/roles that the user needs to possess in order to get access to the field, query or mutation. +By default the roles are of type `string` but they can easily be changed as the decorator is generic - `@Authorized(1, 7, 22)`. + +Thus, authorized users (regardless of their roles) can only read the `publicField` or the `authorizedField` from the `MyObject` object. They will receive `null` when accessing the `hiddenField` field and will receive an error (that will propagate through the whole query tree looking for a nullable field) for the `adminField` when they don't satisfy the role constraints. + +Sample query and mutation guards: + +```ts +@Resolver() +class MyResolver { + @Query() + publicQuery(): MyObject { + return { + publicField: "Some public data", + authorizedField: "Data for logged users only", + adminField: "Top secret info for admin", + }; + } + + @Authorized() + @Query() + authedQuery(): string { + return "Authorized users only!"; + } + + @Authorized("ADMIN", "MODERATOR") + @Mutation() + adminMutation(): string { + return "You are an admin/moderator, you can safely drop the database ;)"; + } +} +``` + +Authorized users (regardless of their roles) will be able to read data from the `publicQuery` and the `authedQuery` queries, but will receive an error when trying to perform the `adminMutation` when their roles don't include `ADMIN` or `MODERATOR`. + +Next, we need to create our auth checker function. Its implementation may depend on our business logic: + +```ts +export const customAuthChecker: AuthChecker = ( + { root, args, context, info }, + roles, +) => { + // Read user from context + // and check the user's permission against the `roles` argument + // that comes from the '@Authorized' decorator, eg. ["ADMIN", "MODERATOR"] + + return true; // or 'false' if access is denied +}; +``` + +The second argument of the `AuthChecker` generic type is `RoleType` - used together with the `@Authorized` decorator generic type. + +Auth checker can be also defined as a class - this way we can leverage the dependency injection mechanism: + +```ts +export class CustomAuthChecker implements AuthCheckerInterface { + constructor( + // Dependency injection + private readonly userRepository: Repository, + ) {} + + check({ root, args, context, info }: ResolverData, roles: string[]) { + const userId = getUserIdFromToken(context.token); + // Use injected service + const user = this.userRepository.getById(userId); + + // Custom logic, e.g.: + return user % 2 === 0; + } +} +``` + +The last step is to register the function or class while building the schema: + +```ts +import { customAuthChecker } from "../auth/custom-auth-checker.ts"; + +const schema = await buildSchema({ + resolvers: [MyResolver], + // Register the auth checking function + // or defining it inline + authChecker: customAuthChecker, +}); +``` + +And it's done! πŸ˜‰ + +If we need silent auth guards and don't want to return authorization errors to users, we can set the `authMode` property of the `buildSchema` config object to `"null"`: + +```ts +const schema = await buildSchema({ + resolvers: ["./**/*.resolver.ts"], + authChecker: customAuthChecker, + authMode: "null", +}); +``` + +It will then return `null` instead of throwing an authorization error. + +## Recipes + +We can also use `TypeGraphQL` with JWT authentication. +Here's an example using `@apollo/server`: + +```ts +import { ApolloServer } from "@apollo/server"; +import { expressMiddleware } from "@apollo/server/express4"; +import express from "express"; +import jwt from "express-jwt"; +import bodyParser from "body-parser"; +import { schema } from "./graphql/schema"; +import { User } from "./User.type"; + +// GraphQL path +const GRAPHQL_PATH = "/graphql"; + +// GraphQL context +type Context = { + user?: User; +}; + +// Express +const app = express(); + +// Apollo server +const server = new ApolloServer({ schema }); +await server.start(); + +// Mount a JWT or other authentication middleware that is run before the GraphQL execution +app.use( + GRAPHQL_PATH, + jwt({ + secret: "TypeGraphQL", + credentialsRequired: false, + }), +); + +// Apply GraphQL server middleware +app.use( + GRAPHQL_PATH, + bodyParser.json(), + expressMiddleware(server, { + // Build context + // 'req.user' comes from 'express-jwt' + context: async ({ req }) => ({ user: req.user }), + }), +); + +// Start server +await new Promise(resolve => app.listen({ port: 4000 }, resolve)); +console.log(`GraphQL server ready at http://localhost:4000/${GRAPHQL_PATH}`); +``` + +Then we can use standard, token based authorization in the HTTP header like in classic REST APIs and take advantage of the `TypeGraphQL` authorization mechanism. + +## Example + +See how this works in the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/authorization). diff --git a/website/versioned_docs/version-2.0.0-rc.1/complexity.md b/website/versioned_docs/version-2.0.0-rc.1/complexity.md new file mode 100644 index 000000000..d3d640430 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-rc.1/complexity.md @@ -0,0 +1,103 @@ +--- +title: Query complexity +id: version-2.0.0-rc.1-complexity +original_id: complexity +--- + +A single GraphQL query can potentially generate a huge workload for a server, like thousands of database operations which can be used to cause DDoS attacks. In order to limit and keep track of what each GraphQL operation can do, `TypeGraphQL` provides the option of integrating with Query Complexity tools like [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity). + +This cost analysis-based solution is very promising, since we can define a β€œcost” per field and then analyze the AST to estimate the total cost of the GraphQL query. Of course all the analysis is handled by `graphql-query-complexity`. + +All we must do is define our complexity cost for the fields, mutations or subscriptions in `TypeGraphQL` and implement `graphql-query-complexity` in whatever GraphQL server that is being used. + +## How to use + +First, we need to pass `complexity` as an option to the decorator on a field, query or mutation. + +Example of complexity + +```ts +@ObjectType() +class MyObject { + @Field({ complexity: 2 }) + publicField: string; + + @Field({ complexity: ({ args, childComplexity }) => childComplexity + 1 }) + complexField: string; +} +``` + +The `complexity` option may be omitted if the complexity value is 1. +Complexity can be passed as an option to any `@Field`, `@FieldResolver`, `@Mutation` or `@Subscription` decorator. If both `@FieldResolver` and `@Field` decorators of the same property have complexity defined, then the complexity passed to the field resolver decorator takes precedence. + +In the next step, we will integrate `graphql-query-complexity` with the server that expose our GraphQL schema over HTTP. +You can use it with `express-graphql` like [in the lib examples](https://github.com/slicknode/graphql-query-complexity/blob/b6a000c0984f7391f3b4e886e3df6a7ed1093b07/README.md#usage-with-express-graphql), however we will use Apollo Server like in our other examples: + +```ts +async function bootstrap() { + // ... Build GraphQL schema + + // Create GraphQL server + const server = new ApolloServer({ + schema, + // Create a plugin to allow query complexity calculation for every request + plugins: [ + { + requestDidStart: async () => ({ + async didResolveOperation({ request, document }) { + /** + * Provides GraphQL query analysis to be able to react on complex queries to the GraphQL server + * It can be used to protect the GraphQL server against resource exhaustion and DoS attacks + * More documentation can be found at https://github.com/ivome/graphql-query-complexity + */ + const complexity = getComplexity({ + // GraphQL schema + schema, + // To calculate query complexity properly, + // check only the requested operation + // not the whole document that may contains multiple operations + operationName: request.operationName, + // GraphQL query document + query: document, + // GraphQL query variables + variables: request.variables, + // Add any number of estimators. The estimators are invoked in order, the first + // numeric value that is being returned by an estimator is used as the field complexity + // If no estimator returns a value, an exception is raised + estimators: [ + // Using fieldExtensionsEstimator is mandatory to make it work with type-graphql + fieldExtensionsEstimator(), + // Add more estimators here... + // This will assign each field a complexity of 1 + // if no other estimator returned a value + simpleEstimator({ defaultComplexity: 1 }), + ], + }); + + // React to the calculated complexity, + // like compare it with max and throw error when the threshold is reached + if (complexity > MAX_COMPLEXITY) { + throw new Error( + `Sorry, too complicated query! ${complexity} exceeded the maximum allowed complexity of ${MAX_COMPLEXITY}`, + ); + } + console.log("Used query complexity points:", complexity); + }, + }), + }, + ], + }); + + // Start server + const { url } = await startStandaloneServer(server, { listen: { port: 4000 } }); + console.log(`GraphQL server ready at ${url}`); +} +``` + +And it's done! πŸ˜‰ + +For more info about how query complexity is computed, please visit [graphql-query-complexity](https://github.com/ivome/graphql-query-complexity). + +## Example + +See how this works in the [simple query complexity example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/query-complexity). diff --git a/website/versioned_docs/version-2.0.0-rc.1/custom-decorators.md b/website/versioned_docs/version-2.0.0-rc.1/custom-decorators.md new file mode 100644 index 000000000..bc2ce7693 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-rc.1/custom-decorators.md @@ -0,0 +1,109 @@ +--- +title: Custom decorators +id: version-2.0.0-rc.1-custom-decorators +original_id: custom-decorators +--- + +Custom decorators are a great way to reduce the boilerplate and reuse some common logic between different resolvers. TypeGraphQL supports two kinds of custom decorators - method and parameter. + +## Method decorators + +Using [middlewares](./middlewares.md) allows to reuse some code between resolvers. To further reduce the boilerplate and have a nicer API, we can create our own custom method decorators. + +They work in the same way as the [reusable middleware function](./middlewares.md#reusable-middleware), however, in this case we need to call `createMethodDecorator` helper function with our middleware logic and return its value: + +```ts +export function ValidateArgs(schema: JoiSchema) { + return createMethodDecorator(async ({ args }, next) => { + // Middleware code that uses custom decorator arguments + + // e.g. Validation logic based on schema using 'joi' + await joiValidate(schema, args); + return next(); + }); +} +``` + +The usage is then very simple, as we have a custom, descriptive decorator - we just place it above the resolver/field and pass the required arguments to it: + +```ts +@Resolver() +export class RecipeResolver { + @ValidateArgs(MyArgsSchema) // Custom decorator + @UseMiddleware(ResolveTime) // Explicit middleware + @Query() + randomValue(@Args() { scale }: MyArgs): number { + return Math.random() * scale; + } +} +``` + +## Parameter decorators + +Parameter decorators are just like the custom method decorators or middlewares but with an ability to return some value that will be injected to the method as a parameter. Thanks to this, it reduces the pollution in `context` which was used as a workaround for the communication between reusable middlewares and resolvers. + +They might be just a simple data extractor function, that makes our resolver more unit test friendly: + +```ts +function CurrentUser() { + return createParamDecorator(({ context }) => context.currentUser); +} +``` + +Or might be a more advanced one that performs some calculations and encapsulates some logic. Compared to middlewares, they allow for a more granular control on executing the code, like calculating fields map based on GraphQL info only when it's really needed (requested by using the `@Fields()` decorator): + +```ts +function Fields(level = 1): ParameterDecorator { + return createParamDecorator(async ({ info }) => { + const fieldsMap: FieldsMap = {}; + // Calculate an object with info about requested fields + // based on GraphQL 'info' parameter of the resolver and the level parameter + // or even call some async service, as it can be a regular async function and we can just 'await' + return fieldsMap; + }); +} +``` + +> Be aware, that `async` function as a custom param decorators logic can make the GraphQL resolver execution slower, so try to avoid them, if possible. + +Then we can use our custom param decorators in the resolvers just like the built-in decorators: + +```ts +@Resolver() +export class RecipeResolver { + constructor(private readonly recipesRepository: Repository) {} + + @Authorized() + @Mutation(returns => Recipe) + async addRecipe( + @Args() recipeData: AddRecipeInput, + // Custom decorator just like the built-in one + @CurrentUser() currentUser: User, + ) { + const recipe: Recipe = { + ...recipeData, + // and use the data returned from custom decorator in the resolver code + author: currentUser, + }; + await this.recipesRepository.save(recipe); + + return recipe; + } + + @Query(returns => Recipe, { nullable: true }) + async recipe( + @Arg("id") id: string, + // Custom decorator that parses the fields from GraphQL query info + @Fields() fields: FieldsMap, + ) { + return await this.recipesRepository.find(id, { + // use the fields map as a select projection to optimize db queries + select: fields, + }); + } +} +``` + +## Example + +See how different kinds of custom decorators work in the [custom decorators and middlewares example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/middlewares-custom-decorators). diff --git a/website/versioned_docs/version-2.0.0-rc.1/dependency-injection.md b/website/versioned_docs/version-2.0.0-rc.1/dependency-injection.md new file mode 100644 index 000000000..dafb0e2c2 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-rc.1/dependency-injection.md @@ -0,0 +1,180 @@ +--- +title: Dependency injection +id: version-2.0.0-rc.1-dependency-injection +original_id: dependency-injection +--- + +Dependency injection is a really useful pattern that helps in decoupling parts of the app. + +TypeGraphQL supports this technique by allowing users to provide their IoC container that will be used by the framework. + +## Basic usage + +The usage of this feature is very simple - all you need to do is register a 3rd party container. + +Example using TypeDI: + +```ts +import { buildSchema } from "type-graphql"; +// IOC container +import { Container } from "typedi"; +import { SampleResolver } from "./resolvers"; + +// Build TypeGraphQL executable schema +const schema = await buildSchema({ + // Array of resolvers + resolvers: [SampleResolver], + // Registry 3rd party IOC container + container: Container, +}); +``` + +Resolvers will then be able to declare their dependencies and TypeGraphQL will use the container to solve them: + +```ts +import { Service } from "typedi"; + +@Service() +@Resolver(of => Recipe) +export class RecipeResolver { + constructor( + // Dependency injection + private readonly recipeService: RecipeService, + ) {} + + @Query(returns => Recipe, { nullable: true }) + async recipe(@Arg("recipeId") recipeId: string) { + // Usage of the injected service + return this.recipeService.getOne(recipeId); + } +} +``` + +A sample recipe service implementation may look like this: + +```ts +import { Service, Inject } from "typedi"; + +@Service() +export class RecipeService { + @Inject("SAMPLE_RECIPES") + private readonly items: Recipe[], + + async getAll() { + return this.items; + } + + async getOne(id: string) { + return this.items.find(item => item.id === id); + } +} +``` + +> Be aware than when you use [InversifyJS](https://github.com/inversify/InversifyJS), you have to bind the resolver class with the [self-binding of concrete types](https://github.com/inversify/InversifyJS/blob/master/wiki/classes_as_id.md#self-binding-of-concrete-types), e.g.: +> +> ```ts +> container.bind(SampleResolver).to(SampleResolver).inSingletonScope(); +> ``` + +## Scoped containers + +Dependency injection is a really powerful pattern, but some advanced users may encounter the need for creating fresh instances of some services or resolvers for every request. Since `v0.13.0`, **TypeGraphQL** supports this feature, that is extremely useful for tracking logs by individual requests or managing stateful services. + +To register a scoped container, we need to make some changes in the server bootstrapping config code. +First we need to provide a container resolver function. It takes the resolver data (like context) as an argument and should return an instance of the container scoped to the request. + +For simple container libraries we may define it inline, e.g. using `TypeDI`: + +```ts +await buildSchema({ + container: (({ context }: ResolverData) => Container.of(context.requestId)); +}; +``` + +The tricky part is where the `context.requestId` comes from. Unfortunately, we need to provide it manually using hooks that are exposed by HTTP GraphQL middleware like `express-graphql`, `@apollo/server` or `graphql-yoga`. + +For some other advanced libraries, we might need to create an instance of the container, place it in the context object and then retrieve it in the `container` getter function: + +```ts +await buildSchema({ + container: (({ context }: ResolverData) => context.container); +}; +``` + +Example using `TypeDI` and `@apollo/server` with the `context` creation method: + +```ts +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { Container } from "typedi"; + +// Create GraphQL server +const server = new ApolloServer({ + // GraphQL schema + schema, +}); + +// Start server +const { url } = await startStandaloneServer(server, { + listen: { port: 4000 }, + // Provide unique context with 'requestId' for each request + context: async () => { + const requestId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // uuid-like + const container = Container.of(requestId.toString()); // Get scoped container + const context = { requestId, container }; // Create context + container.set("context", context); // Set context or other data in container + + return context; + }, +}); +console.log(`GraphQL server ready at ${url}`); +``` + +We also have to dispose the container after the request has been handled and the response is ready. Otherwise, there would be a huge memory leak as the new instances of services and resolvers have been created for each request but they haven't been cleaned up. + +Apollo Server has a [plugins](https://www.apollographql.com/docs/apollo-server/integrations/plugins) feature that supports [`willSendResponse`](https://www.apollographql.com/docs/apollo-server/integrations/plugins/#willsendresponse) lifecycle event. We can leverage it to clean up the container after handling the request. + +Example using `TypeDI` and `@apollo/server` with plugins approach: + +```ts +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { Container } from "typedi"; + +const server = new ApolloServer({ + // GraphQL schema + schema, + // Create a plugin to allow for disposing the scoped container created for every request + plugins: [ + { + requestDidStart: async () => ({ + async willSendResponse(requestContext) { + // Dispose the scoped container to prevent memory leaks + Container.reset(requestContext.contextValue.requestId.toString()); + + // For developers curiosity purpose, here is the logging of current scoped container instances + // Make multiple parallel requests to see in console how this works + const instancesIds = ((Container as any).instances as ContainerInstance[]).map( + instance => instance.id, + ); + console.log("Instances left in memory: ", instancesIds); + }, + }), + }, + ], +}); +``` + +And basically that's it! The configuration of the container is done and TypeGraphQL will be able to use different instances of resolvers for each request. + +The only thing that's left is the container configuration - we need to check out the docs for our container library (`InversifyJS`, `injection-js`, `TypeDI` or other) to get know how to setup the lifetime of the injectable objects (transient, scoped or singleton). + +> Be aware that some libraries (like `TypeDI`) by default create new instances for every scoped container, so you might experience a **significant increase in memory usage** and some slowing down in query resolving speed, so please be careful with using this feature! + +## Example + +You can see how this fits together in the [simple example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/using-container). + +For a more advanced usage example with scoped containers, check out [advanced example with scoped containers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/using-scoped-container). + +Integration with [TSyringe](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/tsyringe). diff --git a/website/versioned_docs/version-2.0.0-rc.1/examples.md b/website/versioned_docs/version-2.0.0-rc.1/examples.md new file mode 100644 index 000000000..942989aab --- /dev/null +++ b/website/versioned_docs/version-2.0.0-rc.1/examples.md @@ -0,0 +1,53 @@ +--- +title: Examples +sidebar_label: List of examples +id: version-2.0.0-rc.1-examples +original_id: examples +--- + +On the [GitHub repository](https://github.com/MichalLytek/type-graphql) there are a few simple [`examples`](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples) of how to use different `TypeGraphQL` features and how well they integrate with 3rd party libraries. + +To run an example, simply go to the subdirectory (e.g. `cd ./simple-usage`), and then start the server (`npx ts-node ./index.ts`). + +Each subdirectory contains a `examples.graphql` file with predefined GraphQL queries/mutations/subscriptions that you can use in Apollo Studio () and play with them by modifying their shape and data. + +## Basics + +- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/simple-usage) + +## Advanced + +- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/enums-and-unions) +- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/simple-subscriptions) +- [Subscriptions (using Redis) \*\*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/redis-subscriptions) +- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/interfaces-inheritance) +- [Extensions (metadata)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/extensions) + +## Features usage + +- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/using-container) + - [Scoped containers](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/using-scoped-container) +- [Authorization](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/authorization) +- [Validation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/automatic-validation) + - [Custom validation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/custom-validation) +- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/interfaces-inheritance) +- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/resolvers-inheritance) +- [Generic types](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/generic-types) +- [Mixin classes](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/mixin-classes) +- [Middlewares and Custom Decorators](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/middlewares-custom-decorators) +- [Query complexity](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/query-complexity) + +## 3rd party libs integration + +- [TypeORM (manual, synchronous) \*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/typeorm-basic-usage) +- [TypeORM (automatic, lazy relations) \*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/typeorm-lazy-relations) +- [MikroORM \*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/mikro-orm) +- [Typegoose \*](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/typegoose) +- [Apollo Federation](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/apollo-federation) +- [Apollo Federation 2](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/apollo-federation-2) +- [Apollo Cache Control](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/apollo-cache) +- [GraphQL Scalars](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/graphql-scalars) +- [TSyringe](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/tsyringe) + +_\* Note that we need to provide the environment variable `DATABASE_URL` with connection parameters to your local database_ \ +_\*\* Note that we need to provide the environment variable `REDIS_URL` with connection parameters to your local Redis instance_ diff --git a/website/versioned_docs/version-2.0.0-rc.1/extensions.md b/website/versioned_docs/version-2.0.0-rc.1/extensions.md new file mode 100644 index 000000000..721aaff79 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-rc.1/extensions.md @@ -0,0 +1,119 @@ +--- +title: Extensions +id: version-2.0.0-rc.1-extensions +original_id: extensions +--- + +The `graphql-js` library allows for putting arbitrary data into GraphQL types config inside the `extensions` property. +Annotating schema types or fields with a custom metadata, that can be then used at runtime by middlewares or resolvers, is a really powerful and useful feature. + +For such use cases, **TypeGraphQL** provides the `@Extensions` decorator, which adds the data we defined to the `extensions` property of the executable schema for the decorated classes, methods or properties. + +> Be aware that this is a low-level decorator and you generally have to provide your own logic to make use of the `extensions` metadata. + +## Using the `@Extensions` decorator + +Adding extensions to the schema type is as simple as using the `@Extensions` decorator and passing it an object of the custom data we want: + +```ts +@Extensions({ complexity: 2 }) +``` + +We can pass several fields to the decorator: + +```ts +@Extensions({ logMessage: "Restricted access", logLevel: 1 }) +``` + +And we can also decorate a type several times. The snippet below shows that this attaches the exact same extensions data to the schema type as the snippet above: + +```ts +@Extensions({ logMessage: "Restricted access" }) +@Extensions({ logLevel: 1 }) +``` + +If we decorate the same type several times with the same extensions key, the one defined at the bottom takes precedence: + +```ts +@Extensions({ logMessage: "Restricted access" }) +@Extensions({ logMessage: "Another message" }) +``` + +The above usage results in your GraphQL type having a `logMessage: "Another message"` property in its extensions. + +TypeGraphQL classes with the following decorators can be annotated with `@Extensions` decorator: + +- `@ObjectType` +- `@InputType` +- `@Field` +- `@Query` +- `@Mutation` +- `@FieldResolver` + +So the `@Extensions` decorator can be placed over the class property/method or over the type class itself, and multiple times if necessary, depending on what we want to do with the extensions data: + +```ts +@Extensions({ roles: ["USER"] }) +@ObjectType() +class Foo { + @Field() + field: string; +} + +@ObjectType() +class Bar { + @Extensions({ roles: ["USER"] }) + @Field() + field: string; +} + +@ObjectType() +class Bar { + @Extensions({ roles: ["USER"] }) + @Extensions({ visible: false, logMessage: "User accessed restricted field" }) + @Field() + field: string; +} + +@Resolver(of => Foo) +class FooBarResolver { + @Extensions({ roles: ["USER"] }) + @Query() + foobar(@Arg("baz") baz: string): string { + return "foobar"; + } + + @Extensions({ roles: ["ADMIN"] }) + @FieldResolver() + bar(): string { + return "foobar"; + } +} +``` + +## Using the extensions data in runtime + +Once we have decorated the necessary types with extensions, the executable schema will contain the extensions data, and we can make use of it in any way we choose. The most common use will be to read it at runtime in resolvers or middlewares and perform some custom logic there. + +Here is a simple example of a global middleware that will be logging a message on field resolver execution whenever the field is decorated appropriately with `@Extensions`: + +```ts +export class LoggerMiddleware implements MiddlewareInterface { + constructor(private readonly logger: Logger) {} + + use({ info }: ResolverData, next: NextFn) { + // extract `extensions` object from GraphQLResolveInfo object to get the `logMessage` value + const { logMessage } = info.parentType.getFields()[info.fieldName].extensions || {}; + + if (logMessage) { + this.logger.log(logMessage); + } + + return next(); + } +} +``` + +## Examples + +You can see more detailed examples of usage [here](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/extensions). diff --git a/website/versioned_docs/version-2.0.0-rc.1/generic-types.md b/website/versioned_docs/version-2.0.0-rc.1/generic-types.md new file mode 100644 index 000000000..c96fe73ff --- /dev/null +++ b/website/versioned_docs/version-2.0.0-rc.1/generic-types.md @@ -0,0 +1,169 @@ +--- +title: Generic Types +id: version-2.0.0-rc.1-generic-types +original_id: generic-types +--- + +[Type Inheritance](./inheritance.md) is a great way to reduce code duplication by extracting common fields to the base class. But in some cases, the strict set of fields is not enough because we might need to declare the types of some fields in a more flexible way, like a type parameter (e.g. `items: T[]` in case of a pagination). + +Hence TypeGraphQL also has support for describing generic GraphQL types. + +## How to? + +Unfortunately, the limited reflection capabilities of TypeScript don't allow for combining decorators with standard generic classes. To achieve behavior like that of generic types, we use the same class-creator pattern like the one described in the [Resolvers Inheritance](./inheritance.md) docs. + +### Basic usage + +Start by defining a `PaginatedResponse` function that creates and returns an abstract `PaginatedResponseClass`: + +```ts +export default function PaginatedResponse() { + abstract class PaginatedResponseClass { + // ... + } + return PaginatedResponseClass; +} +``` + +To achieve generic-like behavior, the function has to be generic and take some runtime argument related to the type parameter: + +```ts +export default function PaginatedResponse(TItemClass: ClassType) { + abstract class PaginatedResponseClass { + // ... + } + return PaginatedResponseClass; +} +``` + +Then, add proper decorators to the class which might be `@ObjectType`, `@InterfaceType` or `@InputType`: + +```ts +export default function PaginatedResponse(TItemClass: ClassType) { + @ObjectType() + abstract class PaginatedResponseClass { + // ... + } + return PaginatedResponseClass; +} +``` + +After that, add fields like in a normal class but using the generic type and parameters: + +```ts +export default function PaginatedResponse(TItemClass: ClassType) { + @ObjectType() + abstract class PaginatedResponseClass { + // Runtime argument + @Field(type => [TItemClass]) + // Generic type + items: TItem[]; + + @Field(type => Int) + total: number; + + @Field() + hasMore: boolean; + } + return PaginatedResponseClass; +} +``` + +Finally, use the generic function factory to create a dedicated type class: + +```ts +@ObjectType() +class PaginatedUserResponse extends PaginatedResponse(User) { + // Add more fields or overwrite the existing one's types + @Field(type => [String]) + otherInfo: string[]; +} +``` + +And then use it in our resolvers: + +```ts +@Resolver() +class UserResolver { + @Query() + users(): PaginatedUserResponse { + // Custom business logic, + // depending on underlying data source and libraries + return { + items, + total, + hasMore, + otherInfo, + }; + } +} +``` + +### Complex generic type values + +When we need to provide something different than a class (object type) for the field type, we need to enhance the parameter type signature and provide the needed types. + +Basically, the parameter that the `PaginatedResponse` function accepts is the value we can provide to `@Field` decorator. +So if we want to return an array of strings as the `items` field, we need to add proper types to the function signature, like `GraphQLScalarType` or `String`: + +```ts +export default function PaginatedResponse( + itemsFieldValue: ClassType | GraphQLScalarType | String | Number | Boolean, +) { + @ObjectType() + abstract class PaginatedResponseClass { + @Field(type => [itemsFieldValue]) + items: TItemsFieldValue[]; + + // ... Other fields + } + return PaginatedResponseClass; +} +``` + +And then provide a proper runtime value (like `String`) while creating a proper subtype of generic `PaginatedResponse` object type: + +```ts +@ObjectType() +class PaginatedStringsResponse extends PaginatedResponse(String) { + // ... +} +``` + +### Types factory + +We can also create a generic class without using the `abstract` keyword. +But with this approach, types created with this kind of factory will be registered in the schema, so this way is not recommended to extend the types for adding fields. + +To avoid generating schema errors of duplicated `PaginatedResponseClass` type names, we must provide our own unique, generated type name: + +```ts +export default function PaginatedResponse(TItemClass: ClassType) { + // Provide a unique type name used in schema + @ObjectType(`Paginated${TItemClass.name}Response`) + class PaginatedResponseClass { + // ... + } + return PaginatedResponseClass; +} +``` + +Then, we can store the generated class in a variable and in order to use it both as a runtime object and as a type, we must also create a type for this new class: + +```ts +const PaginatedUserResponse = PaginatedResponse(User); +type PaginatedUserResponse = InstanceType; + +@Resolver() +class UserResolver { + // Provide a runtime type argument to the decorator + @Query(returns => PaginatedUserResponse) + users(): PaginatedUserResponse { + // Same implementation as in the earlier code snippet + } +} +``` + +## Examples + +A more advanced usage example of the generic types feature can be found in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/generic-types). diff --git a/website/versioned_docs/version-2.0.0-rc.1/inheritance.md b/website/versioned_docs/version-2.0.0-rc.1/inheritance.md new file mode 100644 index 000000000..853e7a848 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-rc.1/inheritance.md @@ -0,0 +1,145 @@ +--- +title: Inheritance +id: version-2.0.0-rc.1-inheritance +original_id: inheritance +--- + +The main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes. + +In object-oriented programming it is common to compose classes using inheritance. Hence, TypeGraphQL supports composing type definitions by extending classes. + +## Types inheritance + +One of the most known principles of software development is DRY - Don't Repeat Yourself - which is about avoiding code redundancy. + +While creating a GraphQL API, it's a common pattern to have pagination args in resolvers, like `skip` and `take`. So instead of repeating ourselves, we declare it once: + +```ts +@ArgsType() +class PaginationArgs { + @Field(type => Int) + skip: number = 0; + + @Field(type => Int) + take: number = 25; +} +``` + +and then reuse it everywhere: + +```ts +@ArgsType() +class GetTodosArgs extends PaginationArgs { + @Field() + onlyCompleted: boolean = false; +} +``` + +This technique also works with input type classes, as well as with object type classes: + +```ts +@ObjectType() +class Person { + @Field() + age: number; +} + +@ObjectType() +class Student extends Person { + @Field() + universityName: string; +} +``` + +Note that both the subclass and the parent class must be decorated with the same type of decorator, like `@ObjectType()` in the example `Person -> Student` above. Mixing decorator types across parent and child classes is prohibited and might result in a schema building error, e.g. we can't decorate the subclass with `@ObjectType()` and the parent with `@InputType()`. + +## Resolver Inheritance + +A special kind of inheritance in TypeGraphQL is resolver class inheritance. This pattern allows us e.g. to create a base CRUD resolver class for our resource/entity, so we don't have to repeat common boilerplate code. + +Since we need to generate unique query/mutation names, we have to create a factory function for our base class: + +```ts +function createBaseResolver() { + abstract class BaseResolver {} + + return BaseResolver; +} +``` + +Be aware that with some `tsconfig.json` settings (like `declarations: true`) we might receive a `[ts] Return type of exported function has or is using private name 'BaseResolver'` error - in this case we might need to use `any` as the return type or create a separate class/interface describing the class methods and properties. + +This factory should take a parameter that we can use to generate the query/mutation names, as well as the type that we would return from the resolvers: + +```ts +function createBaseResolver(suffix: string, objectTypeCls: T) { + abstract class BaseResolver {} + + return BaseResolver; +} +``` + +It's very important to mark the `BaseResolver` class using the `@Resolver` decorator: + +```ts +function createBaseResolver(suffix: string, objectTypeCls: T) { + @Resolver() + abstract class BaseResolver {} + + return BaseResolver; +} +``` + +We can then implement the resolver methods as usual. The only difference is that we can use the `name` decorator option for `@Query`, `@Mutation` and `@Subscription` decorators to overwrite the name that will be emitted in schema: + +```ts +function createBaseResolver(suffix: string, objectTypeCls: T) { + @Resolver() + abstract class BaseResolver { + protected items: T[] = []; + + @Query(type => [objectTypeCls], { name: `getAll${suffix}` }) + async getAll(@Arg("first", type => Int) first: number): Promise { + return this.items.slice(0, first); + } + } + + return BaseResolver; +} +``` + +Now we can create a specific resolver class that will extend the base resolver class: + +```ts +const PersonBaseResolver = createBaseResolver("person", Person); + +@Resolver(of => Person) +export class PersonResolver extends PersonBaseResolver { + // ... +} +``` + +We can also add specific queries and mutations in our resolver class, as always: + +```ts +const PersonBaseResolver = createBaseResolver("person", Person); + +@Resolver(of => Person) +export class PersonResolver extends PersonBaseResolver { + @Mutation() + addPerson(@Arg("input") personInput: PersonInput): Person { + this.items.push(personInput); + return personInput; + } +} +``` + +And that's it! We just need to normally register `PersonResolver` in `buildSchema` and the extended resolver will work correctly. + +We must be aware that if we want to overwrite the query/mutation/subscription from the parent resolver class, we need to generate the same schema name (using the `name` decorator option or the class method name). It will overwrite the implementation along with the GraphQL args and return types. If we only provide a different implementation of the inherited method like `getOne`, it won't work. + +## Examples + +More advanced usage examples of type inheritance (and interfaces) can be found in [the example folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/interfaces-inheritance). + +For a more advanced resolver inheritance example, please go to [this example folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/resolvers-inheritance). diff --git a/website/versioned_docs/version-2.0.0-rc.1/installation.md b/website/versioned_docs/version-2.0.0-rc.1/installation.md new file mode 100644 index 000000000..50fafca7f --- /dev/null +++ b/website/versioned_docs/version-2.0.0-rc.1/installation.md @@ -0,0 +1,67 @@ +--- +title: Installation +id: version-2.0.0-rc.1-installation +original_id: installation +--- + +Before getting started with TypeGraphQL we need to install some additional dependencies and properly configure the TypeScript configuration for our project. + +> #### Prerequisites +> +> Before we begin, we must make sure our development environment includes Node.js and npm. + +## Packages installation + +First, we have to install the main package, as well as [`graphql-js`](https://github.com/graphql/graphql-js) and [`graphql-scalars`](https://github.com/urigo/graphql-scalars) which are peer dependencies of TypeGraphQL: + +```sh +npm install graphql graphql-scalars type-graphql +``` + +Also, the `Reflect.metadata()` shim is required to make the type reflection work: + +```sh +npm install reflect-metadata +# or +npm install core-js +``` + +We must ensure that it is imported at the top of our entry file (before we use/import `type-graphql` or our resolvers): + +```ts +import "reflect-metadata"; +// or +import "core-js/features/reflect"; +``` + +## TypeScript configuration + +It's important to set these options in the `tsconfig.json` file of our project: + +```json +{ + "emitDecoratorMetadata": true, + "experimentalDecorators": true +} +``` + +`TypeGraphQL` is designed to work with Node.js LTS and the latest stable releases. It uses features from ES2021 so we should set our `tsconfig.json` file appropriately: + +```js +{ + "target": "es2021" // Or newer if Node.js version supports it +} +``` + +All in all, the minimal `tsconfig.json` file example looks like this: + +```json +{ + "compilerOptions": { + "target": "es2021", + "module": "commonjs", + "experimentalDecorators": true, + "emitDecoratorMetadata": true + } +} +``` diff --git a/website/versioned_docs/version-2.0.0-rc.1/interfaces.md b/website/versioned_docs/version-2.0.0-rc.1/interfaces.md new file mode 100644 index 000000000..10ceb2538 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-rc.1/interfaces.md @@ -0,0 +1,258 @@ +--- +title: Interfaces +id: version-2.0.0-rc.1-interfaces +original_id: interfaces +--- + +The main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes. + +In object-oriented programming it is common to create interfaces which describe the contract that classes implementing them must adhere to. Hence, TypeGraphQL supports defining GraphQL interfaces. + +Read more about the GraphQL Interface Type in the [official GraphQL docs](https://graphql.org/learn/schema/#interfaces). + +## Abstract classes + +TypeScript has first class support for interfaces. Unfortunately, they only exist at compile-time, so we can't use them to build GraphQL schema at runtime by using decorators. + +Luckily, we can use an abstract class for this purpose. It behaves almost like an interface as it can't be instantiated but it can be implemented by another class. The only difference is that it just won't prevent developers from implementing a method or initializing a field. So, as long as we treat the abstract class like an interface, we can safely use it. + +## Defining interface type + +How do we create a GraphQL interface definition? We create an abstract class and decorate it with the `@InterfaceType()` decorator. The rest is exactly the same as with object types: we use the `@Field` decorator to declare the shape of the type: + +```ts +@InterfaceType() +abstract class IPerson { + @Field(type => ID) + id: string; + + @Field() + name: string; + + @Field(type => Int) + age: number; +} +``` + +We can then use this interface type class like an interface in the object type class definition: + +```ts +@ObjectType({ implements: IPerson }) +class Person implements IPerson { + id: string; + name: string; + age: number; +} +``` + +The only difference is that we have to let TypeGraphQL know that this `ObjectType` is implementing the `InterfaceType`. We do this by passing the param `({ implements: IPerson })` to the decorator. If we implement multiple interfaces, we pass an array of interfaces like so: `({ implements: [IPerson, IAnimal, IMachine] })`. + +It is also allowed to omit the decorators since the GraphQL types will be copied from the interface definition - this way we won't have to maintain two definitions and solely rely on TypeScript type checking for correct interface implementation. + +We can also extend the base interface type abstract class as well because all the fields are inherited and emitted in schema: + +```ts +@ObjectType({ implements: IPerson }) +class Person extends IPerson { + @Field() + hasKids: boolean; +} +``` + +## Implementing other interfaces + +Since `graphql-js` version `15.0`, it's also possible for interface type to [implement other interface types](https://github.com/graphql/graphql-js/pull/2084). + +To accomplish this, we can just use the same syntax that we utilize for object types - the `implements` decorator option: + +```ts +@InterfaceType() +class Node { + @Field(type => ID) + id: string; +} + +@InterfaceType({ implements: Node }) +class Person extends Node { + @Field() + name: string; + + @Field(type => Int) + age: number; +} +``` + +Also, when we implement the interface that already implements other interface, there's no need to put them all in `implements` array in `@ObjectType` decorator option - only the closest one in the inheritance chain is required, e.g.: + +```ts +@ObjectType({ implements: [Person] }) +class Student extends Person { + @Field() + universityName: string; +} +``` + +This example produces following representation in GraphQL SDL: + +```graphql +interface Node { + id: ID! +} + +interface Person implements Node { + id: ID! + name: String! + age: Int! +} + +type Student implements Node & Person { + id: ID! + name: String! + age: Int! + universityName: String! +} +``` + +## Resolvers and arguments + +What's more, we can define resolvers for the interface fields, using the same syntax we would use when defining one for our object type: + +```ts +@InterfaceType() +abstract class IPerson { + @Field() + firstName: string; + + @Field() + lastName: string; + + @Field() + fullName(): string { + return `${this.firstName} ${this.lastName}`; + } +} +``` + +They're inherited by all the object types that implements this interface type but does not provide their own resolver implementation for those fields. + +Additionally, if we want to declare that the interface accepts some arguments, e.g.: + +```graphql +interface IPerson { + avatar(size: Int!): String! +} +``` + +We can just use `@Arg` or `@Args` decorators as usual: + +```ts +@InterfaceType() +abstract class IPerson { + @Field() + avatar(@Arg("size") size: number): string { + return `http://i.pravatar.cc/${size}`; + } +} +``` + +Unfortunately, TypeScript doesn't allow using decorators on abstract methods. +So if we don't want to provide implementation for that field resolver, only to enforce some signature (args and return type), we have to throw an error inside the body: + +```ts +@InterfaceType() +abstract class IPerson { + @Field() + avatar(@Arg("size") size: number): string { + throw new Error("Method not implemented!"); + } +} +``` + +And then we need to extend the interface class and override the method by providing its body - it is required for all object types that implements that interface type: + +```ts +@ObjectType({ implements: IPerson }) +class Person extends IPerson { + avatar(size: number): string { + return `http://i.pravatar.cc/${size}`; + } +} +``` + +In order to extend the signature by providing additional arguments (like `format`), we need to redeclare the whole field signature: + +```ts +@ObjectType({ implements: IPerson }) +class Person implements IPerson { + @Field() + avatar(@Arg("size") size: number, @Arg("format") format: string): string { + return `http://i.pravatar.cc/${size}.${format}`; + } +} +``` + +Resolvers for interface type fields can be also defined on resolvers classes level, by using the `@FieldResolver` decorator: + +```ts +@Resolver(of => IPerson) +class IPersonResolver { + @FieldResolver() + avatar(@Root() person: IPerson, @Arg("size") size: number): string { + return `http://typegraphql.com/${person.id}/${size}`; + } +} +``` + +## Registering in schema + +By default, if the interface type is explicitly used in schema definition (used as a return type of a query/mutation or as some field type), all object types that implement that interface will be emitted in schema, so we don't need to do anything. + +However, in some cases like the `Node` interface that is used in Relay-based systems, this behavior might be not intended when exposing multiple, separates schemas (like a public and the private ones). + +In this situation, we can provide an `{ autoRegisterImplementations: false }` option to the `@InterfaceType` decorator to prevent emitting all this object types in the schema: + +```ts +@InterfaceType({ autoRegisterImplementations: false }) +abstract class Node { + @Field(type => ID) + id: string; +} +``` + +Then we need to add all the object types (that implement this interface type and which we want to expose in selected schema) to the `orphanedTypes` array option in `buildSchema`: + +```ts +const schema = await buildSchema({ + resolvers, + // Provide orphaned object types + orphanedTypes: [Person, Animal, Recipe], +}); +``` + +Be aware that if the object type class is explicitly used as the GraphQL type (like `Recipe` type as the return type of `addRecipe` mutation), it will be emitted regardless the `orphanedTypes` setting. + +## Resolving Type + +Be aware that when our object type is implementing a GraphQL interface type, **we have to return an instance of the type class** in our resolvers. Otherwise, `graphql-js` will not be able to detect the underlying GraphQL type correctly. + +We can also provide our own `resolveType` function implementation to the `@InterfaceType` options. This way we can return plain objects in resolvers and then determine the returned object type by checking the shape of the data object, the same ways [like in unions](./unions.md), e.g.: + +```ts +@InterfaceType({ + resolveType: value => { + if ("grades" in value) { + return "Student"; // Schema name of type string + } + return Person; // Or object type class + }, +}) +abstract class IPerson { + // ... +} +``` + +However in case of interfaces, it might be a little bit more tricky than with unions, as we might not remember all the object types that implements this particular interface. + +## Examples + +For more advanced usage examples of interfaces (and type inheritance), e.g. with query returning an interface type, go to [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/interfaces-inheritance). diff --git a/website/versioned_docs/version-2.0.0-rc.1/middlewares.md b/website/versioned_docs/version-2.0.0-rc.1/middlewares.md new file mode 100644 index 000000000..4f15ff104 --- /dev/null +++ b/website/versioned_docs/version-2.0.0-rc.1/middlewares.md @@ -0,0 +1,189 @@ +--- +title: Middleware and guards +id: version-2.0.0-rc.1-middlewares +original_id: middlewares +--- + +Middleware are pieces of reusable code that can be easily attached to resolvers and fields. By using middleware we can extract the commonly used code from our resolvers and then declaratively attach it using a decorator or even registering it globally. + +## Creating Middleware + +### What is Middleware? + +Middleware is a very powerful but somewhat complicated feature. Basically, middleware is a function that takes 2 arguments: + +- resolver data - the same as resolvers (`root`, `args`, `context`, `info`) +- the `next` function - used to control the execution of the next middleware and the resolver to which it is attached + +We may be familiar with how middleware works in [`express.js`](https://expressjs.com/en/guide/writing-middleware.html) but TypeGraphQL middleware is inspired by [`koa.js`](http://koajs.com/#application). The difference is that the `next` function returns a promise of the value of subsequent middleware and resolver execution from the stack. + +This makes it easy to perform actions before or after resolver execution. So things like measuring execution time are simple to implement: + +```ts +export const ResolveTime: MiddlewareFn = async ({ info }, next) => { + const start = Date.now(); + await next(); + const resolveTime = Date.now() - start; + console.log(`${info.parentType.name}.${info.fieldName} [${resolveTime} ms]`); +}; +``` + +### Intercepting the execution result + +Middleware also has the ability to intercept the result of a resolver's execution. It's not only able to e.g. create a log but also replace the result with a new value: + +```ts +export const CompetitorInterceptor: MiddlewareFn = async (_, next) => { + const result = await next(); + if (result === "typegql") { + return "type-graphql"; + } + return result; +}; +``` + +It might not seem very useful from the perspective of this library's users but this feature was mainly introduced for plugin systems and 3rd-party library integration. Thanks to this, it's possible to e.g. wrap the returned object with a lazy-relation wrapper that automatically fetches relations from a database on demand under the hood. + +### Simple Middleware + +If we only want to do something before an action, like log the access to the resolver, we can just place the `return next()` statement at the end of our middleware: + +```ts +const LogAccess: MiddlewareFn = ({ context, info }, next) => { + const username: string = context.username || "guest"; + console.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`); + return next(); +}; +``` + +### Guards + +Middleware can also break the middleware stack by not calling the `next` function. This way, the result returned from the middleware will be used instead of calling the resolver and returning it's result. + +We can also throw an error in the middleware if the execution must be terminated and an error returned to the user, e.g. when resolver arguments are incorrect. + +This way we can create a guard that blocks access to the resolver and prevents execution or any data return. + +```ts +export const CompetitorDetector: MiddlewareFn = async ({ args }, next) => { + if (args.frameworkName === "type-graphql") { + return "TypeGraphQL"; + } + if (args.frameworkName === "typegql") { + throw new Error("Competitive framework detected!"); + } + return next(); +}; +``` + +### Reusable Middleware + +Sometimes middleware has to be configurable, just like we pass a `roles` array to the [`@Authorized()` decorator](./authorization.md). In this case, we should create a simple middleware factory - a function that takes our configuration as a parameter and returns a middleware that uses the provided value. + +```ts +export function NumberInterceptor(minValue: number): MiddlewareFn { + return async (_, next) => { + const result = await next(); + // Hide values below minValue + if (typeof result === "number" && result < minValue) { + return null; + } + return result; + }; +} +``` + +Remember to call this middleware with an argument, e.g. `NumberInterceptor(3.0)`, when attaching it to a resolver! + +### Error Interceptors + +Middleware can also catch errors that were thrown during execution. This way, they can easily be logged and even filtered for info that can't be returned to the user: + +```ts +export const ErrorInterceptor: MiddlewareFn = async ({ context, info }, next) => { + try { + return await next(); + } catch (err) { + // Write error to file log + fileLog.write(err, context, info); + + // Hide errors from db like printing sql query + if (someCondition(err)) { + throw new Error("Unknown error occurred!"); + } + + // Rethrow the error + throw err; + } +}; +``` + +### Class-based Middleware + +Sometimes our middleware logic can be a bit complicated - it may communicate with a database, write logs to file, etc., so we might want to test it. In that case we create class middleware that is able to benefit from [dependency injection](./dependency-injection.md) and easily mock a file logger or a database repository. + +To accomplish this, we implement a `MiddlewareInterface`. Our class must have the `use` method that conforms with the `MiddlewareFn` signature. Below we can see how the previously defined `LogAccess` middleware looks after the transformation: + +```ts +export class LogAccess implements MiddlewareInterface { + constructor(private readonly logger: Logger) {} + + async use({ context, info }: ResolverData, next: NextFn) { + const username: string = context.username || "guest"; + this.logger.log(`Logging access: ${username} -> ${info.parentType.name}.${info.fieldName}`); + return next(); + } +} +``` + +## How to use + +### Attaching Middleware + +To attach middleware to a resolver, place the `@UseMiddleware()` decorator above the field or resolver declaration. It accepts an array of middleware that will be called in the provided order. We can also pass them without an array as it supports [rest parameters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters): + +```ts +@Resolver() +export class RecipeResolver { + @Query() + @UseMiddleware(ResolveTime, LogAccess) + randomValue(): number { + return Math.random(); + } +} +``` + +We can also attach the middleware to the `ObjectType` fields, the same way as with the [`@Authorized()` decorator](./authorization.md). + +```ts +@ObjectType() +export class Recipe { + @Field() + title: string; + + @Field(type => [Int]) + @UseMiddleware(LogAccess) + ratings: number[]; +} +``` + +### Global Middleware + +However, for common middleware like measuring resolve time or catching errors, it might be annoying to place a `@UseMiddleware(ResolveTime)` decorator on every field/resolver. + +Hence, in TypeGraphQL we can also register a global middleware that will be called for each query, mutation, subscription and field resolver. For this, we use the `globalMiddlewares` property of the `buildSchema` configuration object: + +```ts +const schema = await buildSchema({ + resolvers: [RecipeResolver], + globalMiddlewares: [ErrorInterceptor, ResolveTime], +}); +``` + +### Custom Decorators + +If we want to use middlewares with a more descriptive and declarative API, we can also create a custom method decorators. See how to do this in [custom decorators docs](./custom-decorators.md#method-decorators). + +## Example + +See how different kinds of middlewares work in the [middlewares and custom decorators example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/middlewares-custom-decorators). diff --git a/website/versioned_docs/version-2.0.0-rc.1/migration-guide.md b/website/versioned_docs/version-2.0.0-rc.1/migration-guide.md new file mode 100644 index 000000000..7965bc0dd --- /dev/null +++ b/website/versioned_docs/version-2.0.0-rc.1/migration-guide.md @@ -0,0 +1,102 @@ +--- +title: Migration Guide +sidebar_label: v1.x -> v2.0 +id: version-2.0.0-rc.1-migration-guide +original_id: migration-guide +--- + +> This chapter contains migration guide, that will help you upgrade your codebase from using old Typegraphql `v1.x` into the newest `v2.0` release. +> +> If you just started using TypeGraphQL and you have `v2.0` installed, you can skip this chapter and go straight into the "Advanced guides" section. + +## New `DateTimeISO` scalar name in schema + +One of the breaking change released in `v2.0` is using `Date` scalars from `graphql-scalars` package, instead of custom ones that were built-in in TypegraphQL. + +This means that the exported `GraphQLISODateTime` scalar is registered in schema under a changed name - `DateTimeISO`. If you don't plan to use other `DateTime` scalar in your project and you need to restore the existing scalar name for an easy upgrade to the latest TypeGraphQL version (without rewriting your GraphQL queries), here's a simple snippet for you to use. + +First, you need to create an alias for the `GraphQLDateTimeISO` scalar: + +```ts +import { GraphQLDateTimeISO } from "graphql-scalars"; +import { GraphQLScalarType } from "graphql"; + +const AliasedGraphQLDateTimeISO = new GraphQLScalarType({ + ...GraphQLDateTimeISO.toConfig(), + name: "DateTime", // use old name +}); +``` + +And then register the scalars mapping in the schema you build, in order to overwrite the default date scalar: + +```ts +import { buildSchema } from "type-graphql"; + +const schema = await buildSchema({ + resolvers, + scalarsMap: [{ type: Date, scalar: AliasedGraphQLDateTimeISO }], +}); +``` + +An alternative solution would be to just search for `DateTime` via CTRL+F in your codebase and replace with `DateTimeISO` in your queries, if you don't need the backward compatibility for existing released client apps. + +## Subscriptions + +The new `v2.0` release contains a bunch of breaking changes related to the GraphQL subscriptions feature. + +In previous releases, this feature was build upon the [`graphql-subscriptions`](https://github.com/apollographql/graphql-subscriptions) package and it's `PubSub` system. +However, it's become unmaintained in the last years and some alternatives has been developed in the meantime. + +So since `v2.0`, TypeGraphQL relies on the new [`@graphql-yoga/subscriptions`](https://the-guild.dev/graphql/yoga-server/docs/features/subscriptions) package which is built on top of latest ECMAScript features. It also has own `PubSub` implementation which works in a similar fashion, but has a slightly different API. + +We did out best to hide under the hood all the differences between the APIs of those packages, but some breaking changes had to occurred in the TypeGraphQL API. + +### The `pubSub` option of `buildSchema` + +It is now required to pass the `PubSub` instance as the config option of `buildSchema` function. +Previously, you could omit it and rely on the default one created by TypeGraphQL. + +The reason for this change is that `@graphql-yoga/subscriptions` package allows to create a type-safe `PubSub` instance via the [generic `createPubSub` function](https://the-guild.dev/graphql/yoga-server/v2/features/subscriptions#topics), so you can add type info about the topics and params required while using `.publish()` method. + +Simple example of the new API: + +```ts +import { buildSchema } from "type-graphql"; +import { createPubSub } from "@graphql-yoga/subscriptions"; + +export const pubSub = createPubSub<{ + NOTIFICATIONS: [NotificationPayload]; + DYNAMIC_ID_TOPIC: [number, NotificationPayload]; +}>(); + +const schema = await buildSchema({ + resolver, + pubSub, +}); +``` + +Be aware that you can use any `PubSub` system you want, not only the `graphql-yoga` one. +The only requirement is to comply with the exported `PubSub` interface - having proper `.subscribe()` and `.publish()` methods. + +### No `@PubSub` decorator + +The consequence of not having automatically created, default `PubSub` instance, is that you don't need access to the internally-created `PubSub` instance. + +Hence, the `@PubSub` decorator was removed - please use dependency injection system if you don't want to have a hardcoded import. The corresponding `Publisher` type was also removed as it was not needed anymore. + +### Renamed and removed types + +There was some inconsistency in naming of the decorator option functions argument types, which was unified in the `v2.0` release. + +If you reference those types in your code (`filter` or `subscribe` decorator option functions), make sure you update your type annotation and imports to the new name. + +- `ResolverFilterData` -> `SubscriptionHandlerData` +- `ResolverTopicData` -> `SubscribeResolverData` + +Also, apart from the `Publisher` type mentioned above, the `PubSubEngine` type has been removed and is no longer exported from the package. + +### Topic with Dynamic ID + +As TypeGraphQL uses `@graphql-yoga/subscriptions` under the hood, it also aims to use its features. And one of the extension to the old `PubSub` system used in `v1.x` is ability to not only use dynamic topics but a topic with a dynamic id. + +You can read more about this new feature in [subscription docs](./subscriptions.md#topic-with-dynamic-id). diff --git a/website/versioned_docs/version-2.0.0-rc.1/resolvers.md b/website/versioned_docs/version-2.0.0-rc.1/resolvers.md new file mode 100644 index 000000000..1cb8a7fac --- /dev/null +++ b/website/versioned_docs/version-2.0.0-rc.1/resolvers.md @@ -0,0 +1,352 @@ +--- +title: Resolvers +id: version-2.0.0-rc.1-resolvers +original_id: resolvers +--- + +Besides [declaring GraphQL's object types](./types-and-fields.md), TypeGraphQL allows us to easily create queries, mutations and field resolvers - like normal class methods, similar to REST controllers in frameworks like Java `Spring`, .NET `Web API` or TypeScript [`routing-controllers`](https://github.com/typestack/routing-controllers). + +## Queries and Mutations + +### Resolver classes + +First we create the resolver class and annotate it with the `@Resolver()` decorator. This class will behave like a controller from classic REST frameworks: + +```ts +@Resolver() +class RecipeResolver {} +``` + +We can use a DI framework (as described in the [dependency injection docs](./dependency-injection.md)) to inject class dependencies (like services or repositories) or to store data inside the resolver class - it's guaranteed to be a single instance per app. + +```ts +@Resolver() +class RecipeResolver { + private recipesCollection: Recipe[] = []; +} +``` + +Then we can create class methods which will handle queries and mutations. For example, let's add the `recipes` query to return a collection of all recipes: + +```ts +@Resolver() +class RecipeResolver { + private recipesCollection: Recipe[] = []; + + async recipes() { + // Fake async + return await this.recipesCollection; + } +} +``` + +We also need to do two things. +The first is to add the `@Query` decorator, which marks the class method as a GraphQL query. +The second is to provide the return type. Since the method is async, the reflection metadata system shows the return type as a `Promise`, so we have to add the decorator's parameter as `returns => [Recipe]` to declare it resolves to an array of `Recipe` object types. + +```ts +@Resolver() +class RecipeResolver { + private recipesCollection: Recipe[] = []; + + @Query(returns => [Recipe]) + async recipes() { + return await this.recipesCollection; + } +} +``` + +### Arguments + +Usually, queries have some arguments - it might be the id of a resource, a search phrase or pagination settings. TypeGraphQL allows you to define arguments in two ways. + +First is the inline method using the `@Arg()` decorator. The drawback is the need to repeating the argument name (due to a limitation of the reflection system) in the decorator parameter. As we can see below, we can also pass a `defaultValue` option that will be reflected in the GraphQL schema. + +```ts +@Resolver() +class RecipeResolver { + // ... + @Query(returns => [Recipe]) + async recipes( + @Arg("servings", { defaultValue: 2 }) servings: number, + @Arg("title", { nullable: true }) title?: string, + ): Promise { + // ... + } +} +``` + +This works well when there are 2 - 3 args. But when you have many more, the resolver's method definitions become bloated. In this case we can use a class definition to describe the arguments. It looks like the object type class but it has the `@ArgsType()` decorator on top. + +```ts +@ArgsType() +class GetRecipesArgs { + @Field(type => Int, { nullable: true }) + skip?: number; + + @Field(type => Int, { nullable: true }) + take?: number; + + @Field({ nullable: true }) + title?: string; +} +``` + +We can define default values for optional fields in the `@Field()` decorator using the `defaultValue` option or by using a property initializer - in both cases TypeGraphQL will reflect this in the schema by setting the default value, so users will be able to omit those args while sending a query. + +> Be aware that `defaultValue` works only for input args and fields, like `@Arg`, `@ArgsType` and `@InputType`. +> Setting `defaultValue` does not affect `@ObjectType` or `@InterfaceType` fields as they are for output purposes only. + +Also, this way of declaring arguments allows you to perform validation. You can find more details about this feature in the [validation docs](./validation.md). + +We can also define helper fields and methods for our args or input classes. But be aware that **defining constructors is strictly forbidden** and we shouldn't use them there, as TypeGraphQL creates instances of args and input classes under the hood by itself. + +```ts +import { Min, Max } from "class-validator"; + +@ArgsType() +class GetRecipesArgs { + @Field(type => Int, { defaultValue: 0 }) + @Min(0) + skip: number; + + @Field(type => Int) + @Min(1) + @Max(50) + take = 25; + + @Field({ nullable: true }) + title?: string; + + // Helpers - index calculations + get startIndex(): number { + return this.skip; + } + get endIndex(): number { + return this.skip + this.take; + } +} +``` + +Then all that is left to do is use the args class as the type of the method parameter. +We can use the destructuring syntax to gain access to single arguments as variables, instead of the reference to the whole args object. + +```ts +@Resolver() +class RecipeResolver { + // ... + @Query(returns => [Recipe]) + async recipes(@Args() { title, startIndex, endIndex }: GetRecipesArgs) { + // Example implementation + let recipes = this.recipesCollection; + if (title) { + recipes = recipes.filter(recipe => recipe.title === title); + } + return recipes.slice(startIndex, endIndex); + } +} +``` + +This declaration will result in the following part of the schema in SDL: + +```graphql +type Query { + recipes(skip: Int = 0, take: Int = 25, title: String): [Recipe!] +} +``` + +### Input types + +GraphQL mutations can be similarly created: Declare the class method, use the `@Mutation` decorator, create arguments, provide a return type (if needed) etc. But for mutations we usually use `input` types, hence TypeGraphQL allows us to create inputs in the same way as [object types](./types-and-fields.md) but by using the `@InputType()` decorator: + +```ts +@InputType() +class AddRecipeInput {} +``` + +To ensure we don't accidentally change the property type we leverage the TypeScript type checking system by implementing the `Partial` type: + +```ts +@InputType() +class AddRecipeInput implements Partial {} +``` + +We then declare any input fields we need, using the `@Field()` decorator: + +```ts +@InputType({ description: "New recipe data" }) +class AddRecipeInput implements Partial { + @Field() + title: string; + + @Field({ nullable: true }) + description?: string; +} +``` + +After that we can use the `AddRecipeInput` type in our mutation. We can do this inline (using the `@Arg()` decorator) or as a field of the args class like in the query example above. + +We may also need access to the context. To achieve this we use the `@Ctx()` decorator with the optional user-defined `Context` interface: + +```ts +@Resolver() +class RecipeResolver { + // ... + @Mutation() + addRecipe(@Arg("data") newRecipeData: AddRecipeInput, @Ctx() ctx: Context): Recipe { + // Example implementation + const recipe = RecipesUtils.create(newRecipeData, ctx.user); + this.recipesCollection.push(recipe); + return recipe; + } +} +``` + +Because our method is synchronous and explicitly returns `Recipe`, we can omit the `@Mutation()` type annotation. + +This declaration will result in the following part of the schema in SDL: + +```graphql +input AddRecipeInput { + title: String! + description: String +} +``` + +```graphql +type Mutation { + addRecipe(data: AddRecipeInput!): Recipe! +} +``` + +By using parameter decorators, we can get rid of unnecessary parameters (like `root`) that bloat our method definition and have to be ignored by prefixing the parameter name with `_`. Also, we can achieve a clean separation between GraphQL and our business code by using decorators, so our resolvers and their methods behave just like services which can be easily unit-tested. + +## Field resolvers + +Queries and mutations are not the only type of resolvers. We often create object type field resolvers (e.g. when a `user` type has a `posts` field) which we have to resolve by fetching relational data from the database. + +Field resolvers in TypeGraphQL are very similar to queries and mutations - we create them as a method on the resolver class but with a few modifications. First we declare which object type fields we are resolving by providing the type to the `@Resolver` decorator: + +```ts +@Resolver(of => Recipe) +class RecipeResolver { + // Queries and mutations +} +``` + +Then we create a class method that will become the field resolver. +In our example we have the `averageRating` field in the `Recipe` object type that should calculate the average from the `ratings` array. + +```ts +@Resolver(of => Recipe) +class RecipeResolver { + // Queries and mutations + + averageRating(recipe: Recipe) { + // ... + } +} +``` + +We then mark the method as a field resolver with the `@FieldResolver()` decorator. Since we've already defined the field type in the `Recipe` class definition, there's no need to redefine it. We also decorate the method parameters with the `@Root` decorator in order to inject the recipe object. + +```ts +@Resolver(of => Recipe) +class RecipeResolver { + // Queries and mutations + + @FieldResolver() + averageRating(@Root() recipe: Recipe) { + // ... + } +} +``` + +For enhanced type safety we can implement the `ResolverInterface` interface. +It's a small helper that checks if the return type of the field resolver methods, like `averageRating(...)`, matches the `averageRating` property of the `Recipe` class and whether the first parameter of the method is the actual object type (`Recipe` class). + +```ts +@Resolver(of => Recipe) +class RecipeResolver implements ResolverInterface { + // Queries and mutations + + @FieldResolver() + averageRating(@Root() recipe: Recipe) { + // ... + } +} +``` + +Here is the full implementation of the sample `averageRating` field resolver: + +```ts +@Resolver(of => Recipe) +class RecipeResolver implements ResolverInterface { + // Queries and mutations + + @FieldResolver() + averageRating(@Root() recipe: Recipe) { + const ratingsSum = recipe.ratings.reduce((a, b) => a + b, 0); + return recipe.ratings.length ? ratingsSum / recipe.ratings.length : null; + } +} +``` + +For simple resolvers like `averageRating` or deprecated fields that behave like aliases, you can create field resolvers inline in the object type class definition: + +```ts +@ObjectType() +class Recipe { + @Field() + title: string; + + @Field({ deprecationReason: "Use `title` instead" }) + get name(): string { + return this.title; + } + + @Field(type => [Rate]) + ratings: Rate[]; + + @Field(type => Float, { nullable: true }) + averageRating(@Arg("since") sinceDate: Date): number | null { + const ratings = this.ratings.filter(rate => rate.date > sinceDate); + if (!ratings.length) return null; + + const ratingsSum = ratings.reduce((a, b) => a + b, 0); + return ratingsSum / ratings.length; + } +} +``` + +However, if the code is more complicated and has side effects (i.e. api calls, fetching data from a databases), a resolver class method should be used instead. This way we can leverage the dependency injection mechanism, which is really helpful in testing. For example: + +```ts +import { Repository } from "typeorm"; + +@Resolver(of => Recipe) +class RecipeResolver implements ResolverInterface { + constructor( + // Dependency injection + private readonly userRepository: Repository, + ) {} + + @FieldResolver() + async author(@Root() recipe: Recipe) { + const author = await this.userRepository.findById(recipe.userId); + if (!author) throw new SomethingWentWrongError(); + return author; + } +} +``` + +Note that if a field name of a field resolver doesn't exist in the resolver object type, it will create a field in the schema with this name. This feature is useful when the field is purely calculable (eg. `averageRating` from `ratings` array) and to avoid polluting the class signature. + +## Resolver Inheritance + +Resolver class `inheritance` is an advanced topic covered in the [resolver inheritance docs](./inheritance.md#resolvers-inheritance). + +## Examples + +These code samples are just made up for tutorial purposes. +You can find more advanced, real examples in the [examples folder on the repository](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples). diff --git a/website/versioned_docs/version-2.0.0-rc.1/subscriptions.md b/website/versioned_docs/version-2.0.0-rc.1/subscriptions.md new file mode 100644 index 000000000..8c6ffd82c --- /dev/null +++ b/website/versioned_docs/version-2.0.0-rc.1/subscriptions.md @@ -0,0 +1,213 @@ +--- +title: Subscriptions +id: version-2.0.0-rc.1-subscriptions +original_id: subscriptions +--- + +GraphQL can be used to perform reads with queries and writes with mutations. +However, oftentimes clients want to get updates pushed to them from the server when data they care about changes. +To support that, GraphQL has a third operation: subscription. TypeGraphQL of course has great support for subscription, using the [`@graphql-yoga/subscriptions`](https://the-guild.dev/graphql/yoga-server/docs/features/subscriptions) package created by [`The Guild`](https://the-guild.dev/). + +## Creating Subscriptions + +Subscription resolvers are similar to [queries and mutation resolvers](./resolvers.md) but slightly more complicated. + +First we create a normal class method as always, but this time annotated with the `@Subscription()` decorator. + +```ts +class SampleResolver { + // ... + @Subscription() + newNotification(): Notification { + // ... + } +} +``` + +Then we have to provide the topics we wish to subscribe to. This can be a single topic string, an array of topics or a function to dynamically create a topic based on subscription arguments passed to the query. We can also use TypeScript enums for enhanced type safety. + +```ts +class SampleResolver { + // ... + @Subscription({ + topics: "NOTIFICATIONS", // Single topic + topics: ["NOTIFICATIONS", "ERRORS"] // Or topics array + topics: ({ args, context }) => args.topic // Or dynamic topic function + }) + newNotification(): Notification { + // ... + } +} +``` + +We can also provide the `filter` option to decide which topic events should trigger our subscription. +This function should return a `boolean` or `Promise` type. + +```ts +class SampleResolver { + // ... + @Subscription({ + topics: "NOTIFICATIONS", + filter: ({ payload, args }) => args.priorities.includes(payload.priority), + }) + newNotification(): Notification { + // ... + } +} +``` + +We can also provide a custom subscription logic which might be useful, e.g. if we want to use the Prisma subscription functionality or something similar. + +All we need to do is to use the `subscribe` option which should be a function that returns an `AsyncIterable` or a `Promise`. Example using Prisma 1 subscription feature: + +```ts +class SampleResolver { + // ... + @Subscription({ + subscribe: ({ root, args, context, info }) => { + return context.prisma.$subscribe.users({ mutation_in: [args.mutationType] }); + }, + }) + newNotification(): Notification { + // ... + } +} +``` + +> Be aware that we can't mix the `subscribe` option with the `topics` and `filter` options. If the filtering is still needed, we can use the [`filter` and `map` helpers](https://the-guild.dev/graphql/yoga-server/docs/features/subscriptions#filter-and-map-values) from the `@graphql-yoga/subscriptions` package. + +Now we can implement the subscription resolver. It will receive the payload from a triggered topic of the pubsub system using the `@Root()` decorator. There, we can transform it to the returned shape. + +```ts +class SampleResolver { + // ... + @Subscription({ + topics: "NOTIFICATIONS", + filter: ({ payload, args }) => args.priorities.includes(payload.priority), + }) + newNotification( + @Root() notificationPayload: NotificationPayload, + @Args() args: NewNotificationsArgs, + ): Notification { + return { + ...notificationPayload, + date: new Date(), + }; + } +} +``` + +## Triggering subscription topics + +Ok, we've created subscriptions, but what is the `pubsub` system and how do we trigger topics? + +They might be triggered from external sources like a database but also in mutations, +e.g. when we modify some resource that clients want to receive notifications about when it changes. + +So, let us assume we have this mutation for adding a new comment: + +```ts +class SampleResolver { + // ... + @Mutation(returns => Boolean) + async addNewComment(@Arg("comment") input: CommentInput) { + const comment = this.commentsService.createNew(input); + await this.commentsRepository.save(comment); + return true; + } +} +``` + +First, we need to create the `PubSub` instance. In most cases, we call `createPubSub()` function from `@graphql-yoga/subscriptions` package. Optionally, we can define the used topics and payload type using the type argument, e.g.: + +```ts +import { createPubSub } from "@graphql-yoga/subscriptions"; + +export const pubSub = createPubSub<{ + NOTIFICATIONS: [NotificationPayload]; + DYNAMIC_ID_TOPIC: [number, NotificationPayload]; +}>(); +``` + +Then, we need to register the `PubSub` instance in the `buildSchema()` function options: + +```ts +import { buildSchema } from "type-graphql"; +import { pubSub } from "./pubsub"; + +const schema = await buildSchema({ + resolver, + pubSub, +}); +``` + +Finally, we can use the created `PubSub` instance to trigger the topics and send the payload to all topic subscribers: + +```ts +import { pubSub } from "./pubsub"; + +class SampleResolver { + // ... + @Mutation(returns => Boolean) + async addNewComment(@Arg("comment") input: CommentInput, @PubSub() pubSub: PubSubEngine) { + const comment = this.commentsService.createNew(input); + await this.commentsRepository.save(comment); + // Trigger subscriptions topics + const payload: NotificationPayload = { message: input.content }; + pubSub.publish("NOTIFICATIONS", payload); + return true; + } +} +``` + +And that's it! Now all subscriptions attached to the `NOTIFICATIONS` topic will be triggered when performing the `addNewComment` mutation. + +## Topic with dynamic ID + +The idea of this feature is taken from the `@graphql-yoga/subscriptions` that is used under the hood. +Basically, sometimes you only want to emit and listen for events for a specific entity (e.g. user or product). Dynamic topic ID lets you declare topics scoped to a special identifier, e.g.: + +```ts +@Resolver() +class NotificationResolver { + @Subscription({ + topics: "NOTIFICATIONS", + topicId: ({ context }) => context.userId, + }) + newNotification(@Root() { message }: NotificationPayload): Notification { + return { message, date: new Date() }; + } +} +``` + +Then in your mutation or services, you need to pass the topic id as the second parameter: + +```ts +pubSub.publish("NOTIFICATIONS", userId, { id, message }); +``` + +> Be aware that this feature must be supported by the pubsub system of your choice. +> If you decide to use something different than `createPubSub()` from `@graphql-yoga/subscriptions`, the second argument might be treated as a payload, not dynamic topic id. + +## Using a custom PubSub system + +While TypeGraphQL uses the `@graphql-yoga/subscriptions` package under the hood to handle subscription, there's no requirement to use that implementation of `PubSub`. + +In fact, you can use any pubsub system you want, not only the `graphql-yoga` one. +The only requirement is to comply with the exported `PubSub` interface - having proper `.subscribe()` and `.publish()` methods. + +This is especially helpful for production usage, where we can't rely on the in-memory event emitter, so that we [use distributed pubsub](https://the-guild.dev/graphql/yoga-server/docs/features/subscriptions#distributed-pubsub-for-production). + +## Creating a Subscription Server + +The [bootstrap guide](./bootstrap.md) and all the earlier examples used [`apollo-server`](https://github.com/apollographql/apollo-server) to create an HTTP endpoint for our GraphQL API. + +However, beginning in Apollo Server 3, subscriptions are not supported by the "batteries-included" apollo-server package. To enable subscriptions, you need to follow the guide on their docs page: + + +## Examples + +See how subscriptions work in a [simple example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/simple-subscriptions). You can see there, how simple is setting up GraphQL subscriptions using `graphql-yoga` package. + +For production usage, it's better to use something more scalable like a Redis-based pubsub system - [a working example is also available](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/redis-subscriptions). +However, to launch this example you need to have a running instance of Redis and you might have to modify the example code to provide your connection parameters. diff --git a/website/versioned_docs/version-2.0.0-rc.1/unions.md b/website/versioned_docs/version-2.0.0-rc.1/unions.md new file mode 100644 index 000000000..4db1bf7eb --- /dev/null +++ b/website/versioned_docs/version-2.0.0-rc.1/unions.md @@ -0,0 +1,109 @@ +--- +title: Unions +id: version-2.0.0-rc.1-unions +original_id: unions +--- + +Sometimes our API has to be flexible and return a type that is not specific but one from a range of possible types. An example might be a movie site's search functionality: using the provided phrase we search the database for movies but also actors. So the query has to return a list of `Movie` or `Actor` types. + +Read more about the GraphQL Union Type in the [official GraphQL docs](http://graphql.org/learn/schema/#union-types). + +## Usage + +Let's start by creating the object types from the example above: + +```ts +@ObjectType() +class Movie { + @Field() + name: string; + + @Field() + rating: number; +} +``` + +```ts +@ObjectType() +class Actor { + @Field() + name: string; + + @Field(type => Int) + age: number; +} +``` + +Now let's create an union type from the object types above - the rarely seen `[ ] as const` syntax is to inform TypeScript compiler that it's a tuple, which allows for better TS union type inference: + +```ts +import { createUnionType } from "type-graphql"; + +const SearchResultUnion = createUnionType({ + name: "SearchResult", // Name of the GraphQL union + types: () => [Movie, Actor] as const, // function that returns tuple of object types classes +}); +``` + +Then we can use the union type in the query by providing the `SearchResultUnion` value in the `@Query` decorator return type annotation. +Notice, that we have to explicitly use the decorator return type annotation due to TypeScript's reflection limitations. +For TypeScript compile-time type safety we can also use `typeof SearchResultUnion` which is equal to type `Movie | Actor`. + +```ts +@Resolver() +class SearchResolver { + @Query(returns => [SearchResultUnion]) + async search(@Arg("phrase") phrase: string): Promise> { + const movies = await Movies.findAll(phrase); + const actors = await Actors.findAll(phrase); + + return [...movies, ...actors]; + } +} +``` + +## Resolving Type + +Be aware that when the query/mutation return type (or field type) is a union, we have to return a specific instance of the object type class. Otherwise, `graphql-js` will not be able to detect the underlying GraphQL type correctly when we use plain JS objects. + +However, we can also provide our own `resolveType` function implementation to the `createUnionType` options. This way we can return plain objects in resolvers and then determine the returned object type by checking the shape of the data object, e.g.: + +```ts +const SearchResultUnion = createUnionType({ + name: "SearchResult", + types: () => [Movie, Actor] as const, + // Implementation of detecting returned object type + resolveType: value => { + if ("rating" in value) { + return Movie; // Return object type class (the one with `@ObjectType()`) + } + if ("age" in value) { + return "Actor"; // Or the schema name of the type as a string + } + return undefined; + }, +}); +``` + +**Et VoilΓ !** We can now build the schema and make the example query πŸ˜‰ + +```graphql +query { + search(phrase: "Holmes") { + ... on Actor { + # Maybe Katie Holmes? + name + age + } + ... on Movie { + # For sure Sherlock Holmes! + name + rating + } + } +} +``` + +## Examples + +More advanced usage examples of unions (and enums) are located in [this examples folder](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/enums-and-unions). diff --git a/website/versioned_docs/version-2.0.0-rc.1/validation.md b/website/versioned_docs/version-2.0.0-rc.1/validation.md new file mode 100644 index 000000000..a5a35acee --- /dev/null +++ b/website/versioned_docs/version-2.0.0-rc.1/validation.md @@ -0,0 +1,258 @@ +--- +title: Argument and Input validation +sidebar_label: Validation +id: version-2.0.0-rc.1-validation +original_id: validation +--- + +## Scalars + +The standard way to ensure that inputs and arguments are correct, such as an `email` field that really contains a proper e-mail address, is to use [custom scalars](./scalars.md) e.g. `GraphQLEmail` from [`graphql-custom-types`](https://github.com/stylesuxx/graphql-custom-types). However, creating scalars for all single cases of data types (credit card number, base64, IP, URL) might be cumbersome. + +That's why TypeGraphQL has built-in support for argument and input validation. +By default, we can use the [`class-validator`](https://github.com/typestack/class-validator) library and easily declare the requirements for incoming data (e.g. a number is in the range 0-255 or a password that is longer than 8 characters) thanks to the awesomeness of decorators. + +We can also use other libraries or our own custom solution, as described in [custom validators](#custom-validator) section. + +## `class-validator` + +### How to use + +First, we need to install the `class-validator` package: + +```sh +npm install class-validator +``` + +Then we decorate the input/arguments class with the appropriate decorators from `class-validator`. +So we take this: + +```ts +@InputType() +export class RecipeInput { + @Field() + title: string; + + @Field({ nullable: true }) + description?: string; +} +``` + +...and turn it into this: + +```ts +import { MaxLength, Length } from "class-validator"; + +@InputType() +export class RecipeInput { + @Field() + @MaxLength(30) + title: string; + + @Field({ nullable: true }) + @Length(30, 255) + description?: string; +} +``` + +Then we need to enable the auto-validate feature (as it's disabled by default) by simply setting `validate: true` in `buildSchema` options, e.g.: + +```ts +const schema = await buildSchema({ + resolvers: [RecipeResolver], + validate: true, // Enable 'class-validator' integration +}); +``` + +And that's it! πŸ˜‰ + +TypeGraphQL will automatically validate our inputs and arguments based on the definitions: + +```ts +@Resolver(of => Recipe) +export class RecipeResolver { + @Mutation(returns => Recipe) + async addRecipe(@Arg("input") recipeInput: RecipeInput): Promise { + // 100% sure that the input is correct + console.assert(recipeInput.title.length <= 30); + console.assert(recipeInput.description.length >= 30); + console.assert(recipeInput.description.length <= 255); + } +} +``` + +Of course, [there are many more decorators](https://github.com/typestack/class-validator#validation-decorators) we have access to, not just the simple `@Length` decorator used in the example above, so take a look at the `class-validator` documentation. + +This feature is enabled by default. However, we can disable it if we must: + +```ts +const schema = await buildSchema({ + resolvers: [RecipeResolver], + validate: false, // Disable automatic validation or pass the default config object +}); +``` + +And we can still enable it per resolver's argument if we need to: + +```ts +class RecipeResolver { + @Mutation(returns => Recipe) + async addRecipe(@Arg("input", { validate: true }) recipeInput: RecipeInput) { + // ... + } +} +``` + +The `ValidatorOptions` object used for setting features like [validation groups](https://github.com/typestack/class-validator#validation-groups) can also be passed: + +```ts +class RecipeResolver { + @Mutation(returns => Recipe) + async addRecipe( + @Arg("input", { validate: { groups: ["admin"] } }) + recipeInput: RecipeInput, + ) { + // ... + } +} +``` + +Note that by default, the `skipMissingProperties` setting of the `class-validator` is set to `true` because GraphQL will independently check whether the params/fields exist or not. +Same goes to `forbidUnknownValues` setting which is set to `false` because the GraphQL runtime checks for additional data, not described in schema. + +GraphQL will also check whether the fields have correct types (String, Int, Float, Boolean, etc.) so we don't have to use the `@IsOptional`, `@Allow`, `@IsString` or the `@IsInt` decorators at all! + +However, when using nested input or arrays, we always have to use [`@ValidateNested()` decorator](https://github.com/typestack/class-validator#validating-nested-objects) or [`{ each: true }` option](https://github.com/typestack/class-validator#validating-arrays) to make nested validation work properly. + +### Response to the Client + +When a client sends incorrect data to the server: + +```graphql +mutation ValidationMutation { + addRecipe( + input: { + # Too long! + title: "Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet" + } + ) { + title + creationDate + } +} +``` + +the [`ArgumentValidationError`](https://github.com/MichalLytek/type-graphql/blob/master/src/errors/ArgumentValidationError.ts) will be thrown. + +By default, the `apollo-server` package from the [bootstrap guide](./bootstrap.md) will format the error to match the `GraphQLFormattedError` interface. So when the `ArgumentValidationError` occurs, the client will receive this JSON with a nice `validationErrors` property inside of `extensions.exception`: + +```json +{ + "errors": [ + { + "message": "Argument Validation Error", + "locations": [ + { + "line": 2, + "column": 3 + } + ], + "path": ["addRecipe"], + "extensions": { + "code": "INTERNAL_SERVER_ERROR", + "exception": { + "validationErrors": [ + { + "target": { + "title": "Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet" + }, + "value": "Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet", + "property": "title", + "children": [], + "constraints": { + "maxLength": "title must be shorter than or equal to 30 characters" + } + } + ], + "stacktrace": [ + "Error: Argument Validation Error", + " at Object. (/type-graphql/src/resolvers/validate-arg.ts:29:11)", + " at Generator.throw ()", + " at rejected (/type-graphql/node_modules/tslib/tslib.js:105:69)", + " at processTicksAndRejections (internal/process/next_tick.js:81:5)" + ] + } + } + } + ], + "data": null +} +``` + +Of course we can also create our own custom implementation of the `formatError` function provided in the `ApolloServer` config options which will transform the `GraphQLError` with a `ValidationError` array in the desired output format (e.g. `extensions.code = "ARGUMENT_VALIDATION_ERROR"`). + +### Automatic Validation Example + +To see how this works, check out the [simple real life example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/automatic-validation). + +### Caveats + +Even if we don't use the validation feature (and we have provided `{ validate: false }` option to `buildSchema`), we still need to have `class-validator` installed as a dev dependency in order to compile our app without errors using `tsc`. + +An alternative solution that allows to completely get rid off big `class-validator` from our project's `node_modules` folder is to suppress the `error TS2307: Cannot find module 'class-validator'` TS error by providing `"skipLibCheck": true` setting in `tsconfig.json`. + +## Custom validator + +We can also use other libraries than `class-validator` together with TypeGraphQL. + +To integrate it, all we need to do is to provide a custom function. +It receives three parameters: + +- `argValue` which is the injected value of `@Arg()` or `@Args()` +- `argType` which is a runtime type information (e.g. `String` or `RecipeInput`) +- `resolverData` which holds the resolver execution context, described as generic type `ResolverData` + +This function can be an async function and should return nothing (`void`) when validation passes, or throw an error when validation fails. +So be aware of this while trying to wrap another library in `validateFn` function for TypeGraphQL. + +Then we provide this function as a `validateFn` option in `buildSchema`. +Example using [decorators library for Joi validators (`joiful`)](https://github.com/joiful-ts/joiful): + +```ts +const schema = await buildSchema({ + // ... + validateFn: argValue => { + // Call joiful validate + const { error } = joiful.validate(argValue); + if (error) { + // Throw error on failed validation + throw error; + } + }, +}); +``` + +The `validateFn` option is also supported as a `@Arg()` or `@Args()` decorator option, e.g.: + +```ts +@Resolver() +class SampleResolver { + @Query() + sampleQuery( + @Arg("sampleArg", { + validateFn: (argValue, argType) => { + // Do something here with arg value and type... + }, + }) + sampleArg: string, + ): string { + // ... + } +} +``` + +> Be aware that when using custom validator, the error won't be wrapped with `ArgumentValidationError` like for the built-in `class-validator` validation. + +### Custom Validation Example + +To see how this works, check out the [simple custom validation integration example](https://github.com/MichalLytek/type-graphql/tree/v2.0.0-rc.1/examples/custom-validation). diff --git a/website/versioned_sidebars/version-0.16.0-sidebars.json b/website/versioned_sidebars/version-0.16.0-sidebars.json index 0d1410e01..1f53a759d 100644 --- a/website/versioned_sidebars/version-0.16.0-sidebars.json +++ b/website/versioned_sidebars/version-0.16.0-sidebars.json @@ -1,8 +1,6 @@ { "version-0.16.0-docs": { - "Introduction": [ - "version-0.16.0-introduction" - ], + "Introduction": ["version-0.16.0-introduction"], "Beginner guides": [ "version-0.16.0-getting-started", "version-0.16.0-types-and-fields", @@ -23,19 +21,12 @@ "version-0.16.0-middlewares", "version-0.16.0-complexity" ], - "Others": [ - "version-0.16.0-emit-schema", - "version-0.16.0-browser-usage" - ] + "Others": ["version-0.16.0-emit-schema", "version-0.16.0-browser-usage"] }, "version-0.16.0-examples": { - "Examples": [ - "version-0.16.0-examples" - ] + "Examples": ["version-0.16.0-examples"] }, "version-0.16.0-others": { - "Others": [ - "version-0.16.0-faq" - ] + "Others": ["version-0.16.0-faq"] } } diff --git a/website/versioned_sidebars/version-0.17.0-sidebars.json b/website/versioned_sidebars/version-0.17.0-sidebars.json index 0dcbc674b..2449d56cf 100644 --- a/website/versioned_sidebars/version-0.17.0-sidebars.json +++ b/website/versioned_sidebars/version-0.17.0-sidebars.json @@ -1,8 +1,6 @@ { "version-0.17.0-docs": { - "Introduction": [ - "version-0.17.0-introduction" - ], + "Introduction": ["version-0.17.0-introduction"], "Beginner guides": [ "version-0.17.0-installation", "version-0.17.0-getting-started", @@ -26,19 +24,12 @@ "version-0.17.0-middlewares", "version-0.17.0-complexity" ], - "Others": [ - "version-0.17.0-emit-schema", - "version-0.17.0-browser-usage" - ] + "Others": ["version-0.17.0-emit-schema", "version-0.17.0-browser-usage"] }, "version-0.17.0-examples": { - "Examples": [ - "version-0.17.0-examples" - ] + "Examples": ["version-0.17.0-examples"] }, "version-0.17.0-others": { - "Others": [ - "version-0.17.0-faq" - ] + "Others": ["version-0.17.0-faq"] } } diff --git a/website/versioned_sidebars/version-0.17.4-sidebars.json b/website/versioned_sidebars/version-0.17.4-sidebars.json index a24e3fac0..68f2ff82b 100644 --- a/website/versioned_sidebars/version-0.17.4-sidebars.json +++ b/website/versioned_sidebars/version-0.17.4-sidebars.json @@ -1,8 +1,6 @@ { "version-0.17.4-docs": { - "Introduction": [ - "version-0.17.4-introduction" - ], + "Introduction": ["version-0.17.4-introduction"], "Beginner guides": [ "version-0.17.4-installation", "version-0.17.4-getting-started", @@ -27,19 +25,12 @@ "version-0.17.4-custom-decorators", "version-0.17.4-complexity" ], - "Others": [ - "version-0.17.4-emit-schema", - "version-0.17.4-browser-usage" - ] + "Others": ["version-0.17.4-emit-schema", "version-0.17.4-browser-usage"] }, "version-0.17.4-examples": { - "Examples": [ - "version-0.17.4-examples" - ] + "Examples": ["version-0.17.4-examples"] }, "version-0.17.4-others": { - "Others": [ - "version-0.17.4-faq" - ] + "Others": ["version-0.17.4-faq"] } } diff --git a/website/versioned_sidebars/version-1.0.0-sidebars.json b/website/versioned_sidebars/version-1.0.0-sidebars.json index 0952e2858..b3947e2cd 100644 --- a/website/versioned_sidebars/version-1.0.0-sidebars.json +++ b/website/versioned_sidebars/version-1.0.0-sidebars.json @@ -1,8 +1,6 @@ { "version-1.0.0-docs": { - "Introduction": [ - "version-1.0.0-introduction" - ], + "Introduction": ["version-1.0.0-introduction"], "Beginner guides": [ "version-1.0.0-installation", "version-1.0.0-getting-started", @@ -29,10 +27,7 @@ "version-1.0.0-custom-decorators", "version-1.0.0-complexity" ], - "Integrations": [ - "version-1.0.0-prisma", - "version-1.0.0-nestjs" - ], + "Integrations": ["version-1.0.0-prisma", "version-1.0.0-nestjs"], "Others": [ "version-1.0.0-emit-schema", "version-1.0.0-performance", @@ -40,13 +35,9 @@ ] }, "version-1.0.0-examples": { - "Examples": [ - "version-1.0.0-examples" - ] + "Examples": ["version-1.0.0-examples"] }, "version-1.0.0-others": { - "Others": [ - "version-1.0.0-faq" - ] + "Others": ["version-1.0.0-faq"] } } diff --git a/website/versioned_sidebars/version-2.0.0-beta.3-sidebars.json b/website/versioned_sidebars/version-2.0.0-beta.3-sidebars.json new file mode 100644 index 000000000..d11fc8616 --- /dev/null +++ b/website/versioned_sidebars/version-2.0.0-beta.3-sidebars.json @@ -0,0 +1,53 @@ +{ + "version-2.0.0-beta.3-docs": { + "Introduction": [ + "version-2.0.0-beta.3-introduction" + ], + "Beginner guides": [ + "version-2.0.0-beta.3-installation", + "version-2.0.0-beta.3-getting-started", + "version-2.0.0-beta.3-types-and-fields", + "version-2.0.0-beta.3-resolvers", + "version-2.0.0-beta.3-bootstrap", + "version-2.0.0-beta.3-esm" + ], + "Advanced guides": [ + "version-2.0.0-beta.3-scalars", + "version-2.0.0-beta.3-enums", + "version-2.0.0-beta.3-unions", + "version-2.0.0-beta.3-interfaces", + "version-2.0.0-beta.3-subscriptions", + "version-2.0.0-beta.3-directives", + "version-2.0.0-beta.3-extensions" + ], + "Features": [ + "version-2.0.0-beta.3-dependency-injection", + "version-2.0.0-beta.3-authorization", + "version-2.0.0-beta.3-validation", + "version-2.0.0-beta.3-inheritance", + "version-2.0.0-beta.3-generic-types", + "version-2.0.0-beta.3-middlewares", + "version-2.0.0-beta.3-custom-decorators", + "version-2.0.0-beta.3-complexity" + ], + "Integrations": [ + "version-2.0.0-beta.3-prisma", + "version-2.0.0-beta.3-nestjs" + ], + "Others": [ + "version-2.0.0-beta.3-emit-schema", + "version-2.0.0-beta.3-performance", + "version-2.0.0-beta.3-browser-usage" + ] + }, + "version-2.0.0-beta.3-examples": { + "Examples": [ + "version-2.0.0-beta.3-examples" + ] + }, + "version-2.0.0-beta.3-others": { + "Others": [ + "version-2.0.0-beta.3-faq" + ] + } +} diff --git a/website/versioned_sidebars/version-2.0.0-beta.4-sidebars.json b/website/versioned_sidebars/version-2.0.0-beta.4-sidebars.json new file mode 100644 index 000000000..f70cfc03b --- /dev/null +++ b/website/versioned_sidebars/version-2.0.0-beta.4-sidebars.json @@ -0,0 +1,59 @@ +{ + "version-2.0.0-beta.4-docs": { + "Introduction": [ + "version-2.0.0-beta.4-introduction" + ], + "Beginner guides": [ + "version-2.0.0-beta.4-installation", + "version-2.0.0-beta.4-getting-started", + "version-2.0.0-beta.4-types-and-fields", + "version-2.0.0-beta.4-resolvers", + "version-2.0.0-beta.4-bootstrap", + "version-2.0.0-beta.4-esm" + ], + "Migration guide": [ + "version-2.0.0-beta.4-migration-guide" + ], + "Advanced guides": [ + "version-2.0.0-beta.4-scalars", + "version-2.0.0-beta.4-enums", + "version-2.0.0-beta.4-unions", + "version-2.0.0-beta.4-interfaces", + "version-2.0.0-beta.4-subscriptions", + "version-2.0.0-beta.4-directives", + "version-2.0.0-beta.4-extensions" + ], + "Features": [ + "version-2.0.0-beta.4-dependency-injection", + "version-2.0.0-beta.4-authorization", + "version-2.0.0-beta.4-validation", + "version-2.0.0-beta.4-inheritance", + "version-2.0.0-beta.4-generic-types", + "version-2.0.0-beta.4-middlewares", + "version-2.0.0-beta.4-custom-decorators", + "version-2.0.0-beta.4-complexity" + ], + "Integrations": [ + "version-2.0.0-beta.4-prisma", + "version-2.0.0-beta.4-nestjs" + ], + "Others": [ + "version-2.0.0-beta.4-emit-schema", + "version-2.0.0-beta.4-performance" + ], + "Recipes": [ + "version-2.0.0-beta.4-browser-usage", + "version-2.0.0-beta.4-aws-lambda" + ] + }, + "version-2.0.0-beta.4-examples": { + "Examples": [ + "version-2.0.0-beta.4-examples" + ] + }, + "version-2.0.0-beta.4-others": { + "Others": [ + "version-2.0.0-beta.4-faq" + ] + } +} diff --git a/website/versions.json b/website/versions.json index d7c613e5d..0eaf52812 100644 --- a/website/versions.json +++ b/website/versions.json @@ -1,4 +1,8 @@ [ + "2.0.0-rc.1", + "2.0.0-beta.6", + "2.0.0-beta.4", + "2.0.0-beta.3", "1.2.0-rc.1", "1.1.1", "1.1.0",